<?php
/**
* @version	$Id: order_items_tag_processor.php 16516 2017-01-20 14:12:22Z 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 OrderItemsTagProcessor extends kDBTagProcessor
{
	function PrintGrid($params)
	{
		/** @var kDBList $order */
		$order = $this->Application->recallObject('ord');

		if ( $order->GetDBField('Status') != ORDER_STATUS_INCOMPLETE ) {
			$params['grid'] = $params['NotEditable'];
		}
		else {
			$params['grid'] = $params['Editable'];
		}

		return $this->Application->ProcessParsedTag('m', 'ParseBlock', $params);
	}

	function IsTangible($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		return $object->GetDBField('Type') == PRODUCT_TYPE_TANGIBLE;
	}

	function HasQty($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		return in_array($object->GetDBField('Type'), Array (PRODUCT_TYPE_TANGIBLE, 6));
	}

	function HasDiscount($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		return (float)$object->GetDBField('ItemDiscount') ? 1 : 0;
	}

	function HasOptions($params)
	{
		$object = $this->getObject($params);
		$item_data = @unserialize($object->GetDBField('ItemData'));
		return isset($item_data['Options']);
	}

	function PrintOptions($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		$item_data = @unserialize($object->GetDBField('ItemData'));

		$render_as = $this->SelectParam($params, 'render_as');
		$block_params['name'] = $render_as;

		/** @var kProductOptionsHelper $opt_helper */
		$opt_helper = $this->Application->recallObject('kProductOptionsHelper');

		$o = '';
		$options = $item_data['Options'];
		foreach ($options as $opt => $val) {
			if ( !is_array($val) ) {
				$val = kUtil::unescape($val, kUtil::ESCAPE_HTML); // TODO: Not sure why we're unescaping.
			}
			$key_data = $opt_helper->ConvertKey($opt, $object->GetDBField('ProductId'));

			$parsed = $opt_helper->ExplodeOptionValues($key_data);
			if ( $parsed ) {
				$values = $parsed['Values'];
				$prices = $parsed['Prices'];
				$price_types = $parsed['PriceTypes'];
			}
			else {
				$values = array ();
				$prices = array ();
				$price_types = array ();
			}

			$key = $key_data['Name'];
			/*if (is_array($val)) {
				$val = join(',', $val);
			}*/

			/** @var LanguagesItem $lang */
			$lang = $this->Application->recallObject('lang.current');

			if ( $render_as ) {
				$block_params['option'] = $key;
				if ( is_array($val) ) {
					$block_params['value'] = $val;
					$block_params['type'] = $key_data['OptionType'];
					$block_params['price'] = $prices;
					$block_params['price_type'] = $price_types;
				}
				else {
					$price_type = array_key_exists($val, $price_types) ? $price_types[$val] : '';
					$price = array_key_exists($val, $prices) ? $prices[$val] : '';

					if ( $price_type == '$' ) {
						$iso = $this->GetISO($params['currency']);
						$value = $this->AddCurrencySymbol($lang->formatNumber($this->ConvertCurrency($price, $iso), 2), $iso, true); // true to force sign
						$block_params['price'] = $value;
						$block_params['price_type'] = '';
						$block_params['sign'] = ''; // sign is included in the formatted value
					}
					else {
						$block_params['price'] = $price;
						$block_params['price_type'] = $price_type;
						$block_params['sign'] = $price >= 0 ? '+' : '-';
					}

					// TODO: consider escaping in template instead
					$block_params['value'] = kUtil::escape($val);
					$block_params['type'] = $key_data['OptionType'];
				}
				$o .= $this->Application->ParseBlock($block_params, 1);
			}
			else {
				$o .= $key . ': ' . $val . '<br>';
			}
		}
		return $o;
	}

	function ProductsInStock($params)
	{
		$object = $this->getObject($params);

		if (!$object->GetDBField('InventoryStatus')) {
			// unlimited count available
			return false;
		}

		if ($object->GetDBField('InventoryStatus') == 2) {
			$poc_table = $this->Application->getUnitOption('poc', 'TableName');
			$sql = 'SELECT QtyInStock
					FROM '.$poc_table.'
					WHERE (ProductId = '.$object->GetDBField('ProductId').') AND (Availability = 1) AND (CombinationCRC = '.$object->GetDBField('OptionsSalt').')';
			$ret = $this->Conn->GetOne($sql);
		}
		else {
			$ret = $object->GetDBField('QtyInStock');
		}

		return $ret;
	}

	function PrintOptionValues($params)
	{
		$block_params['name'] = $params['render_as'];

		/** @var Array $values */
		$values = $this->Application->Parser->GetParam('value');

		$prices = $this->Application->Parser->GetParam('price');
		$price_types = $this->Application->Parser->GetParam('price_type');

		$o = '';
		$i = 0;
		foreach ($values as $val) {
			$i++;
			$val = kUtil::unescape($val, kUtil::ESCAPE_HTML); // TODO: Not sure why we're unescaping.

			// TODO: consider escaping in template instead
			$block_params['value'] = kUtil::escape($val);

			if ($price_types[$val] == '$') {
				$iso = $this->GetISO($params['currency']);
				$value = $this->AddCurrencySymbol(sprintf("%.2f", $this->ConvertCurrency($prices[$val], $iso)), $iso, true); // true to force sign
				$block_params['price'] = $value;
				$block_params['price_type'] = '';
				$block_params['sign'] = ''; // sign is included in the formatted value
			}
			else {
				$block_params['price'] = $prices[$val];
				$block_params['price_type'] = $price_types[$val];
				$block_params['sign'] = $prices[$val] >= 0 ? '+' : '-';
			}
			$block_params['is_last'] = $i == count($values);
			$o.= $this->Application->ParseBlock($block_params, 1);
		}
		return $o;
	}

	/*function ConvertKey($key, &$object)
	{
		static $mapping = null;
		if (is_null($mapping) || !isset($mapping[$object->GetDBField('ProductId')])) {
			$table = TABLE_PREFIX.'ProductOptions';
			$sql = 'SELECT * FROM '.$table.' WHERE ProductId = '.$object->GetDBField('ProductId');
			$mapping[$object->GetDBField('ProductId')] = $this->Conn->Query($sql, 'ProductOptionId');
		}
		return $mapping[$object->GetDBField('ProductId')][$key];
	}*/

	function PrintList($params)
	{
		$list =& $this->GetList($params);
		$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');

		$list->Query();
		$o = '';
		$list->GoFirst();

		$block_params = $this->prepareTagParams($params);
		$block_params['name'] = $this->SelectParam($params, 'render_as,block');
		$block_params['pass_params'] = 'true';

		/** @var kCatDBItem $product_object */
		$product_object = $this->Application->recallObject('p', 'p', Array ('skip_autoload' => true));

		$i = 0;
		$product_id = $product_object->GetID();
		$product_id_get = $this->Application->GetVar('p_id');
		$category_id_backup = $this->Application->GetVar('m_cat_id');

		while (!$list->EOL()) {
			// load product used in orderitem
			$this->Application->SetVar($this->getPrefixSpecial() . '_id', $list->GetDBField($id_field)); // for edit/delete links using GET
			$this->Application->SetVar('p_id', $list->GetDBField('ProductId'));
			$product_object->Load($list->GetDBField('ProductId')); // correct product load

			$this->Application->SetVar('m_cat_id', $product_object->GetDBField('CategoryId'));

			$block_params['is_last'] = ($i == $list->GetSelectedCount() - 1);

			$o .= $this->Application->ParseBlock($block_params, 1);
			$list->GoNext();
			$i++;
		}

		// restore IDs used in cycle
		$this->Application->SetVar('p_id', $product_id_get);
		$this->Application->SetVar('m_cat_id', $category_id_backup);
		$this->Application->DeleteVar($this->getPrefixSpecial() . '_id');

		if ( $product_id ) {
			$product_object->Load($product_id);
		}

		return $o;
	}

	function DisplayOptionsPricing($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		if ( $object->GetDBField('OptionsSelectionMode') == 1 ) {
			return false;
		}

		$item_data = unserialize($object->GetDBField('ItemData'));
		if ( !is_array($item_data) ) {
			return false;
		}

		$options = getArrayValue($item_data, 'Options');

		/** @var kProductOptionsHelper $helper */
		$helper = $this->Application->recallObject('kProductOptionsHelper');

		$crc = $helper->OptionsSalt($options, true);

		$sql = 'SELECT COUNT(*)
				FROM ' . TABLE_PREFIX . 'ProductOptionCombinations
				WHERE CombinationCRC = ' . $crc . ' AND ProductId = ' . $object->GetDBField('ProductId') . ' AND (Price != 0 OR (PriceType = 1 AND Price = 0))';

		return $this->Conn->GetOne($sql) == 0; // no overriding combinations found
	}

	function RowIndex($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		return $object->GetDBField('ProductId') . ':' . $object->GetDBField('OptionsSalt') . ':' . $object->GetDBField('BackOrderFlag');
	}

	function FreePromoShippingAvailable($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		/** @var OrderHelper $order_helper */
		$order_helper = $this->Application->recallObject('OrderHelper');

		return $order_helper->eligibleForFreePromoShipping($object);
	}
}
