<?php
class ModelExtensionShippingCanadapost extends Model {
	function getQuote($address) {

		$this->load->language('extension/shipping/canadapost');

		$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('shipping_canadapost_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");

		if (!$this->config->get('shipping_canadapost_geo_zone_id')) {
			$status = true;
		} elseif ($query->num_rows) {
			$status = true;
		} else {
			$status = false;
		}

		$error = '';

		$quote_data = array();

		if($this->config->get('shipping_canadapost_country') !==  null){
			$countryId = $this->config->get('shipping_canadapost_country');
		} else {
			$countryId = 0;
		}

	$cartData = $this->cart->getProducts();
	foreach($cartData as $datas){
		if($datas['height'] > 0 || $datas['width'] > 0 || $datas['length'] > 0){
    $weightClassId = $this->db->query("SELECT weight_class_id as id FROM " . DB_PREFIX . "weight_class_description WHERE unit = 'kg'");
    //Cart total weight
    $cartTotalWeight = $this->cart->getWeight();

    if ($cartTotalWeight) {
	    if (is_array($countryId)) {
		     	if (in_array($address['country_id'],$countryId)) {
					if ($status) {


						$weight = $this->weight->convert($this->cart->getWeight(), $this->config->get('config_weight_class_id'), $weightClassId->row['id']);


			         	$service = $this->config->get('shipping_canadapost_service');
						//Url for rest api
						if (!$this->config->get('shipping_canadapost_test')) {
			            //Url for Production mode
							    $service_url = 'https://soa-gw.canadapost.ca/rs/ship/price';
						} else {
							   //Url for Development mode
							    $service_url = 'https://ct.soa-gw.canadapost.ca/rs/ship/price';
						}

			         	//Xml contain all the requiered data to send request to canada post shipping api
						$xml  = '<?xml version="1.0" encoding="UTF-8"?>';
			            $xml .= ' <mailing-scenario xmlns="http://www.canadapost.ca/ws/ship/rate-v3">';
			            $xml .= '   <customer-number>' . $this->config->get('shipping_canadapost_customer_number') . '</customer-number>';
			            $xml .= '   <parcel-characteristics>';
			            $xml .= '     <weight>'. substr($weight, 0, 4) . '</weight>';
			            $xml .= '    </parcel-characteristics>';
			            $xml .= '   <services>';
			            foreach ($service as  $value) {
			            	$xml .= '     <service-code>'.$value.'</service-code>';
			            }
						$xml .= '   </services>';

						if ($this->config->get('shipping_canadapost_origin_address') == 'custom') {
							$originPostalCode = str_replace(" ", "", $this->config->get('shipping_canadapost_postcode'));
						} else {
							$originPostalCode = str_replace(" ", "", $this->config->get('config_geocode'));
						}

			            $xml .= '   <origin-postal-code>'. strtoupper($originPostalCode) .'</origin-postal-code>';
			            $xml .= '   <destination>';
			            if($address['iso_code_2']=='CA') {
							$postcode = str_replace(" ", "", $address['postcode']);

				            $xml .= '     <domestic>';
				            $xml .= '       <postal-code>'.strtoupper(trim($postcode)).'</postal-code>';
				            $xml .= '     </domestic>';
			            } else if($address['iso_code_2']=='US') {
			            	$xml .= '     <united-states>';
				            $xml .= '       <zip-code>'.$address['postcode'].'</zip-code>';
				            $xml .= '     </united-states>';
			            } else {
			            	$xml .= '     <international>';
				            $xml .= '       <country-code>'.$address['iso_code_2'].'</country-code>';
				            $xml .= '      </international>';
			            }

			            $xml .= '   </destination>';
						$xml .= ' </mailing-scenario>';

			            //curl for sending request to canada post shipping api (REST API)
						$curl = curl_init($service_url);
						curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
						curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
						curl_setopt($curl, CURLOPT_CAINFO, realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . '/includes/modules/shipping/canadapost/cacert.pem');
						curl_setopt($curl, CURLOPT_POST, true);
						curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
						curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
						curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
						curl_setopt($curl, CURLOPT_USERPWD, $this->config->get('shipping_canadapost_api_key').':'.$this->config->get('shipping_canadapost_api_password'));
						curl_setopt($curl, CURLOPT_HTTPHEADER,array('Content-Type: application/vnd.cpc.ship.rate-v3+xml','Accept: application/vnd.cpc.ship.rate-v3+xml'));
						$curl_response = curl_exec($curl);

						//Response code for Curl request
						$responseCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);

						// $curl_response = curl_exec($curl);

						if ($responseCode == 0) {
							$curl = curl_init($service_url);
							curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
							curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
							curl_setopt($curl, CURLOPT_CAINFO, realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . '/includes/modules/shipping/canadapost/cacert.pem');
							curl_setopt($curl, CURLOPT_POST, true);
							curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
							curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
							curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
							curl_setopt($curl, CURLOPT_USERPWD, $this->config->get('shipping_canadapost_api_key').':'.$this->config->get('shipping_canadapost_api_password'));
							curl_setopt($curl, CURLOPT_HTTPHEADER,array('Content-Type: application/vnd.cpc.ship.rate-v3+xml','Accept: application/vnd.cpc.ship.rate-v3+xml'));
							$curl_response = curl_exec($curl);

							//Response code for Curl request
							$responseCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);

							curl_close($curl);
						}

						$dom = new DOMDocument('1.0', 'UTF-8');
						if ($curl_response && $responseCode) {
							$dom->loadXml($curl_response);

							//Response code 200 indicates Success for Curl request
							if($responseCode == 200) {
								$priceQuotes = $dom->getElementsByTagName('price-quote');

								foreach ($priceQuotes as  $value) {
									$serviceName = $value->getElementsByTagName('service-name')->item(0)->nodeValue;
									$serviceCode = $value->getElementsByTagName('service-code')->item(0)->nodeValue;
									$Cost = $value->getElementsByTagName('due')->item(0)->nodeValue;
									$title = $this->language->get('text_' . $serviceCode);
									//Initialize Cost if handling fees is enabale
									if($this->config->get('shipping_canadapost_handling_fee_status')) {
										//handling fee is added Cost based on Fixed amount or percentage amount
										if(($this->config->get('shipping_canadapost_handling_fee') == 1)  && $this->config->get('shipping_canadapost_fee_amount'))  {
											$Cost += $this->config->get('shipping_canadapost_fee_amount');
										} else if(($this->config->get('shipping_canadapost_handling_fee') == 0) && $this->config->get('shipping_canadapost_fee_amount')) {
											$Cost += ($Cost * ($this->config->get('shipping_canadapost_fee_amount'))/100);
										}

									 }
									//To check if free delivery service method is applicable then Delivery is Free of Cost
									$CostWithTax = $this->tax->calculate($this->currency->convert($Cost, $this->session->data['currency'],$this->config->get('config_currency')), $this->config->get('shipping_canadapost_tax_class_id'), $this->config->get('config_tax'));
									if( $serviceCode == ($this->config->get('shipping_canadapost_domestic_free_method')) || $serviceCode == ($this->config->get('shipping_canadapost_usa_free_method')) || $serviceCode == ($this->config->get('shipping_canadapost_inn_free_method'))) {
									   $Cost =0;
									   $CostWithTax = 0;
									   //Free of Cost
									}

									//Amount will not charge if status is enabled and matches amount cretria for free delivery

									if($this->config->get('shipping_canadapost_free_shipping_min_amount')) {
									   if($this->config->get('shipping_canadapost_free_shipping_amount_value')) {
											   $free = $this->currency->convert($this->config->get('shipping_canadapost_free_shipping_amount_value'), $this->session->data['currency'], $this->config->get('config_currency'));

											    if($this->cart->getSubTotal() == $free || $this->cart->getSubTotal() > $free){
											 	 $Cost=0;
								 	 $CostWithTax = 0;
										    }
										}
									}

									//Show expected-delivery-date if enabled time estimated field
									if($this->config->get('shipping_canadapost_time_estimated')) {
										//To check if tag expected-delivery-date exist
										if(isset($value->getElementsByTagName('expected-delivery-date')->item(0)->nodeValue)) {
											$expectedDeliveryDate = $value->getElementsByTagName('expected-delivery-date')->item(0)->nodeValue;

												$date=date_create($expectedDeliveryDate);

												//To add delivery time offset value to estimated delivery time
												if($this->config->get('shipping_canadapost_delivery_time_offset')) {
													$dateValue = $this->config->get('shipping_canadapost_delivery_time_offset'). 'days';
													date_add($date,date_interval_create_from_date_string($dateValue));
													$expectedDeliveryDate = date_format($date,"Y-m-d");

												}

										}
										//To check if expectedDeliveryDate has value
										if(isset($expectedDeliveryDate)){
											$title .= ' - '.$this->language->get('text_eta') . ' ' .$expectedDeliveryDate;
										}

									}
									// Store data for each applicable shipping services
									$quote_data[$serviceName] = array(
										'code'         => 'canadapost.'.$serviceName,
										'title'        => $title,
										'cost'         => $this->currency->convert($CostWithTax, $this->session->data['currency'], $this->config->get('config_currency')),
										'tax_class_id' => $this->config->get('shipping_canadapost_tax_class_id'),
										'text'         => $this->currency->format($CostWithTax, $this->session->data['currency'], 1.0000000)
									);
								}
							} else {
								switch ($responseCode) {
											case 400:
										 $error = "The Postal Code".' "'.$address['postcode'].'" '."is not Valid Postal Code For Selected Country";
										 break;
									 case 401:
										$error = $this->language->get('text_error_authentication');
										break;
									case 403:
										$error = $this->language->get('text_error_authentication');
										break;
									case 1740:
										$error = $this->language->get('text_error_postalCode');
										break;
									case 2653:
										$error = $this->language->get('text_error_postalCode_provinence');
										break;
									case 9112:
										$error = $this->language->get('text_error_country');
										break;
									case 'AA002':
										$error = $this->language->get('text_error_endpoints');
										break;
									case 7266:
										$error = $this->language->get('text_error_postalCode');
										break;
									default:
										$error = $dom->getElementsByTagName('description')->item(0)->nodeValue;
								}

							}
						}

					}
				} else {
					$error = $this->language->get('text_error_country');
				}
		    }
		} else {
			$error = $this->language->get('text_error_total_wieght');
		}
        //display error to users
        if(!$this->config->get('shipping_canadapost_show_error_to_user')){
          $error = '';
        }

		$method_data = array();

		if ($quote_data || $error) {
			$title =  isset($this->config->get('shipping_canadapost_title')[$this->config->get('config_language_id')]) ?  $this->config->get('shipping_canadapost_title')[$this->config->get('config_language_id')] : $this->language->get('text_title');

			$method_data = array(
				'code'       => $this->config->get('shipping_canadapost_title'),
				'title'      => $title,
				'quote'      => $quote_data,
				'sort_order' => $this->config->get('shipping_canadapost_sort_order'),
				'error'      => $error
			);
		}
		return $method_data;
	}else{
		echo "<h3>Please add dimension of Product to see options of Canada Courier</h3>";
	}
}
	}

	public function getShipment($order_id = 0, $product_id = 0) {
        $result =   $this->db->query("SELECT tracking FROM " . DB_PREFIX . "candapost_shipment WHERE product_id = '" . (int)$product_id . "' AND order_id = '" . (int)$order_id . "'")->row;
		return $result ;


	}

}
