<?php
//==============================================================================
// Automatic Shipping v303.1
// 
// Author: Clear Thinking, LLC
// E-mail: johnathan@getclearthinking.com
// Website: http://www.getclearthinking.com
// 
// All code within this file is copyright Clear Thinking, LLC.
// You may not copy or reuse code within this file without written permission.
//==============================================================================

class ModelExtensionTotalAutomaticShipping extends Model {		
	private $type = 'total';
	private $name = 'automatic_shipping';
	
	public function getTotal($total_input) {
		$total_data = &$total_input['totals'];
		$order_total = &$total_input['total'];
		$taxes = &$total_input['taxes'];
		
		$settings = $this->getSettings();
		
		if (!$settings['status'] || isset($this->session->data['shipping_method']) || !$this->cart->hasShipping()) {
			return;
		}
		
		// Prevent infinite loops
		if (isset($this->session->data[$this->name])) return;
		$this->session->data[$this->name] = true;
		
		// Set address info
		$addresses = array();
		$this->load->model('account/address');
		foreach (array('shipping') as $address_type) {
			if (empty($address) || $address_type == 'payment') {
				$address = array();
				
				if ($this->customer->isLogged()) 										$address = $this->model_account_address->getAddress($this->customer->getAddressId());
				if (!empty($this->session->data['country_id']))							$address['country_id'] = $this->session->data['country_id'];
				if (!empty($this->session->data['zone_id']))							$address['zone_id'] = $this->session->data['zone_id'];
				if (!empty($this->session->data['postcode']))							$address['postcode'] = $this->session->data['postcode'];
				if (!empty($this->session->data['city']))								$address['city'] = $this->session->data['city'];
				
				if (!empty($this->session->data[$address_type . '_country_id']))		$address['country_id'] = $this->session->data[$address_type . '_country_id'];
				if (!empty($this->session->data[$address_type . '_zone_id']))			$address['zone_id'] = $this->session->data[$address_type . '_zone_id'];
				if (!empty($this->session->data[$address_type . '_postcode']))			$address['postcode'] = $this->session->data[$address_type . '_postcode'];
				if (!empty($this->session->data[$address_type . '_city']))				$address['city'] = $this->session->data[$address_type . '_city'];
				
				if (!empty($this->session->data['guest'][$address_type]))				$address = $this->session->data['guest'][$address_type];
				if (!empty($this->session->data[$address_type . '_address_id']))		$address = $this->model_account_address->getAddress($this->session->data[$address_type . '_address_id']);
				if (!empty($this->session->data[$address_type . '_address']))			$address = $this->session->data[$address_type . '_address'];
			}
			
			if (empty($address['address_1']))	$address['address_1'] = '';
			if (empty($address['address_2']))	$address['address_2'] = '';
			if (empty($address['city']))		$address['city'] = '';
			if (empty($address['postcode']))	$address['postcode'] = '';
			if (empty($address['country_id']))	$address['country_id'] = $this->config->get('config_country_id');
			if (empty($address['zone_id']))		$address['zone_id'] =  $this->config->get('config_zone_id');
			
			$country_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "country WHERE country_id = " . (int)$address['country_id']);
			$address['country'] = (isset($country_query->row['name'])) ? $country_query->row['name'] : '';
			$address['iso_code_2'] = (isset($country_query->row['iso_code_2'])) ? $country_query->row['iso_code_2'] : '';
			
			$zone_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone WHERE zone_id = " . (int)$address['zone_id']);
			$address['zone'] = (isset($zone_query->row['name'])) ? $zone_query->row['name'] : '';
			$address['zone_code'] = (isset($zone_query->row['code'])) ? $zone_query->row['code'] : '';
			
			$addresses[$address_type] = $address;
			
			$addresses[$address_type]['geo_zones'] = array();
			$geo_zones_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE country_id = " . (int)$address['country_id'] . " AND (zone_id = 0 OR zone_id = " . (int)$address['zone_id'] . ")");
			if ($geo_zones_query->num_rows) {
				foreach ($geo_zones_query->rows as $geo_zone) {
					$addresses[$address_type]['geo_zones'][] = $geo_zone['geo_zone_id'];
				}
			} else {
				$addresses[$address_type]['geo_zones'] = array(0);
			}
		}
		
		$address = $addresses['shipping'];
		
		// Find lowest cost shipping option from selected shipping methods
		$quote_data = array();
		
		$shipping_methods_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "extension WHERE `type` = 'shipping' ORDER BY `code` ASC");
		
		foreach ($shipping_methods_query->rows as $method) {
			if ((!$this->config->get($method['code'] . '_status') && !$this->config->get('shipping_' . $method['code'] . '_status')) || !in_array($method['code'], explode(';', $settings['shipping_methods']))) {
				continue;
			}
			
			if (version_compare(VERSION, '2.3', '<')) {
				$this->load->model('shipping/' . $method['code']);
				$quote = $this->{'model_shipping_'.$method['code']}->getQuote($address);
			} else {
				$this->load->model('extension/shipping/' . $method['code']);
				$quote = $this->{'model_extension_shipping_'.$method['code']}->getQuote($address);
			}
			
			if (empty($quote)) continue;
			
			$quote_data[$method['code']] = array( 
				'title'			=> $quote['title'],
				'quote'			=> $quote['quote'],
				'sort_order'	=> $quote['sort_order'],
				'error'			=> $quote['error'],
			);
		}
		
		$title = '';
		$cost = 999999;
		$tax_class_id = '';
		$code = '';
		
		foreach ($quote_data as $quote) {
			if (!empty($quote['error'])) continue;
			foreach ($quote['quote'] as $q) {
				if ($q['cost'] < $cost) {
					$title = $q['title'];
					$cost = $q['cost'];
					$tax_class_id = $q['tax_class_id'];
					$code = $q['code'];
				}
			}
		}
		
		// Set Order Total data
		$this->cache->delete($this->name);
		unset($this->session->data[$this->name]);
		
		if (!$title) return;
		
		$this->session->data['shipping_method'] = array(
			'title'			=> $title,
			'cost'			=> $cost,
			'tax_class_id'	=> $tax_class_id,
			'code'			=> $code,
		);
		
		/*
		$total_data[] = array(
			'code'			=> $this->name,
			'title'			=> $title,
			'text'			=> $this->currency->format($cost, $this->session->data['currency']),
			'value'			=> $cost,
			'sort_order'	=> $settings['sort_order'],
		);
		
		$order_total += $cost;
		
		if ($tax_class_id) {
			foreach ($this->tax->getRates($cost, $tax_class_id) as $tax_rate) {
				$taxes[$tax_rate['tax_rate_id']] = (isset($taxes[$tax_rate['tax_rate_id']])) ? $taxes[$tax_rate['tax_rate_id']] + $tax_rate['amount'] : $tax_rate['amount'];
			}
		}
		*/
	}
	
	//------------------------------------------------------------------------------
	// Private functions
	//------------------------------------------------------------------------------
	private function getSettings() {
		$code = (version_compare(VERSION, '3.0', '<') ? '' : $this->type . '_') . $this->name;
		
		$settings = array();
		$settings_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE `code` = '" . $this->db->escape($code) . "' ORDER BY `key` ASC");
		
		foreach ($settings_query->rows as $setting) {
			$value = $setting['value'];
			if ($setting['serialized']) {
				$value = (version_compare(VERSION, '2.1', '<')) ? unserialize($setting['value']) : json_decode($setting['value'], true);
			}
			$split_key = preg_split('/_(\d+)_?/', str_replace($code . '_', '', $setting['key']), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
			
				if (count($split_key) == 1)	$settings[$split_key[0]] = $value;
			elseif (count($split_key) == 2)	$settings[$split_key[0]][$split_key[1]] = $value;
			elseif (count($split_key) == 3)	$settings[$split_key[0]][$split_key[1]][$split_key[2]] = $value;
			elseif (count($split_key) == 4)	$settings[$split_key[0]][$split_key[1]][$split_key[2]][$split_key[3]] = $value;
			else 							$settings[$split_key[0]][$split_key[1]][$split_key[2]][$split_key[3]][$split_key[4]] = $value;
		}
		
		return $settings;
	}
}
?>