<?php
/**
* @version	$Id: currencies_event_handler.php 16601 2018-04-06 12:07:55Z 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 CurrenciesEventHandler extends kDBEventHandler {

	/**
	 * Allows to override standard permission mapping
	 *
	 * @return void
	 * @access protected
	 * @see kEventHandler::$permMapping
	 */
	protected function mapPermissions()
	{
		parent::mapPermissions();

		$permissions = Array (
			// admin
			'OnUpdateRate' => Array ('self' => 'add|edit'),
			'OnUpdateRates' => Array ('self' => 'advanced:update_rate|add|edit'),
			'OnDisableUnused' => Array ('self' => 'edit'),

			// front
			'OnChangeCurrency' => Array ('self' => true),
			'OnItemBuild' => Array ('self' => true),
		);

		$this->permMapping = array_merge($this->permMapping, $permissions);
	}

	/**
	 * Returns ID of current item to be edited
	 * by checking ID passed in get/post as prefix_id
	 * or by looking at first from selected ids, stored.
	 * Returned id is also stored in Session in case
	 * it was explicitly passed as get/post
	 *
	 * @param kEvent $event
	 * @return int
	 * @access public
	 */
	public function getPassedID(kEvent $event)
	{
		if ( $event->Special == 'current' ) {
			return Array ('ISO' => $this->Application->RecallVar('curr_iso'));
		}

		return parent::getPassedID($event);
	}

	/**
	 * Enter description here...
	 *
	 * @param kEvent $event
	 */
	function OnSetPrimary($event)
	{
		if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
			$event->status = kEvent::erFAIL;
			return;
		}

		/** @var kDBItem $object */
		$object = $event->getObject();

		$object->SetDBField('IsPrimary', 1);
		$object->Update();
	}

	/**
	 * Occurs before updating item
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnBeforeItemUpdate(kEvent $event)
	{
		parent::OnBeforeItemUpdate($event);

		/** @var kDBItem $object */
		$object = $event->getObject();

		if ( $object->GetDBField('IsPrimary') && $object->Validate() ) {
			$sql = 'UPDATE ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
					SET IsPrimary = 0
					WHERE CurrencyId <> ' . $object->GetDBField('CurrencyId');
			$this->Conn->Query($sql);

			$object->SetDBField('Status', 1);
		}

		$object->SetDBField('Modified_date', adodb_mktime());
		$object->SetDBField('Modified_time', adodb_mktime());

		if ( $object->GetDBField('Status') == 0 ) {
			$sql = 'DELETE FROM ' . $this->Application->getUnitOption('ptc', 'TableName') . '
					WHERE CurrencyId = ' . $object->GetDBField('CurrencyId');
			$this->Conn->Query($sql);
		}
	}

	/**
	 * Apply any custom changes to list's sql query
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 * @see kDBEventHandler::OnListBuild()
	 */
	protected function SetCustomQuery(kEvent $event)
	{
		parent::SetCustomQuery($event);

		/** @var kDBList $object */
		$object = $event->getObject();

		if ( $event->Special == 'active' ) {
			$object->addFilter('status_filter', '%1$s.Status = 1');
		}

		if ( !$this->Application->isAdminUser ) {
			$object->addFilter('status_filter', $object->TableName . '.Status = 1');
		}

		// site domain currency picker
		if ( $event->Special == 'selected' || $event->Special == 'available' ) {
			/** @var EditPickerHelper $edit_picker_helper */
			$edit_picker_helper = $this->Application->recallObject('EditPickerHelper');

			$edit_picker_helper->applyFilter($event, 'Currencies');
			$object->addFilter('status_filter', '%1$s.Status = ' . STATUS_ACTIVE);
		}

		// apply domain-based currency filtering
		$currencies = $this->Application->siteDomainField('Currencies');

		if ( strlen($currencies) ) {
			$currencies = explode('|', substr($currencies, 1, -1));
			$object->addFilter('domain_filter', '%1$s.CurrencyId IN (' . implode(',', $currencies) . ')');
		}
	}

	/**
	 * Saves content of temp table into live and
	 * redirects to event' default redirect (normally grid template)
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnSave(kEvent $event)
	{
		$this->Application->StoreVar('saved_curr_ids', $this->Application->RecallVar($event->Prefix . '_selected_ids'));

		parent::OnSave($event);
	}

	/**
	 * Enter description here...
	 *
	 * @param kEvent $event
	 */
	function OnDisableUnused($event)
	{
		$unused_ids = $this->Application->GetVar('unused_ids');

		if ( $unused_ids ) {
			$sql = 'UPDATE ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
					SET Status = 0
					WHERE CurrencyId IN(' . $unused_ids . ') AND IsPrimary <> 1';
			$this->Conn->Query($sql);
		}
	}

	/**
	 * Enter description here...
	 *
	 * @param kEvent $event
	 */
	function OnUpdateRate($event)
	{
		if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
			$event->status = kEvent::erFAIL;
			return;
		}

		$event->CallSubEvent('OnPreSave');
		$rate_source = $this->Application->ConfigValue('Comm_ExchangeRateSource');
		$rate_source_classes = Array(	2 => 'FRNYCurrencyRates',
										3 => 'ECBCurrencyRates',
										1 => 'BankLVCurrencyRates'
									);
		$rates_class = $rate_source_classes[$rate_source];
		$rates = $this->Application->recallObject($rates_class);

		$rates->GetRatesData();

		/** @var kDBItem $object */
		$object = $event->getObject();

		$iso = $object->GetDBField('ISO');
		$rates->StoreRates($iso);
		if($rates->GetRate($iso, 'PRIMARY'))
		{
			$event->status=kEvent::erSUCCESS;
		}
		else
		{
			$event->status=kEvent::erFAIL;
			$event->redirect=false;
			$object->SetError('RateToPrimary', 'couldnt_retrieve_rate', 'la_couldnt_retrieve_rate');
		}
	}

	/**
	 * Enter description here...
	 *
	 * @param kEvent $event
	 */
	function OnUpdateRates($event)
	{
		if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
			$event->status = kEvent::erFAIL;
			return;
		}

		$ids = $this->StoreSelectedIDs($event);
		$event->setEventParam('ids', $ids);
		$ids = $event->getEventParam('ids');

		if ( $ids ) {
			$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
			$sql = 'SELECT ISO FROM ' . $table_name . ' WHERE CurrencyId IN (' . implode(',', $ids) . ')';
			$iso_list = $this->Conn->GetCol($sql);
		}
		else {
			$iso_list = array();
		}

		$rate_source = $this->Application->ConfigValue('Comm_ExchangeRateSource');
		$rate_source_classes = Array(	2 => 'FRNYCurrencyRates',
										3 => 'ECBCurrencyRates',
										1 => 'BankLVCurrencyRates'
									);
		$rates_class = $rate_source_classes[$rate_source];
		$rates = $this->Application->recallObject($rates_class);

		$rates->GetRatesData();

		if($iso_list)
		{
			$rates->StoreRates($iso_list);
		}
		else
		{
			$rates->StoreRates();
		}
	}

	/**
	 * Allows to change currency to given one
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnChangeCurrency($event)
	{
		$currency_iso = $this->Application->GetVar('curr_iso');
		$available_currencies = $this->Application->siteDomainField('Currencies');

		if ($available_currencies) {
			if (strpos($available_currencies, '|' . $currency_iso . '|') === false) {
				// currency isn't allowed in site domain
				return ;
			}
		}

		$this->Application->StoreVar('curr_iso', $currency_iso);

		$passed = explode(',', $this->Application->GetVar('passed'));
		$prefix_index = array_search($event->getPrefixSpecial(), $passed);

		if ( $prefix_index !== false ) {
			unset($passed[$prefix_index]);
			$this->Application->SetVar('passed', implode(',', $passed));
		}
	}

	/**
	 * Changes default module to custom (when available)
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnAfterConfigRead(kEvent $event)
	{
		parent::OnAfterConfigRead($event);

		// make sure, that currency Translation is on current language
		$language_id = $this->Application->GetVar('m_lang');
		$calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields');

		foreach ($calculated_fields[''] as $field_name => $field_expression) {
			$calculated_fields[''][$field_name] = str_replace('%4$s', $language_id, $field_expression);
		}

		$this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields);
	}
}
