<?php
namespace  OfficeBrain\Bundle\ShippingEstimatorBundle\Helper;

use OfficeBrain\Bundle\ShippingEstimatorBundle\Manager\AbstractManager\ShippingEstimatorAbstract;
use FedEx\RateService\SimpleType;
/* use FedEx\RateService\ComplexType;
use FedEx\RateService\SimpleType; */
#use FedEx\TrackService;
use Symfony\Component\Yaml\Parser;

class FedexHelper extends ShippingEstimatorAbstract
{
	protected $accountNumber;
	protected $meterNumber;
	protected $accessKey;
	protected $accessKeyPassword;
	protected $environment;
	protected $container;
	protected $rateRequest;
	public    $allParameter;
	protected $requestedShipment;
	protected $packageCount;
	protected $response;
	protected $reply;
	protected $pathWsdl;

	public function __construct($type,$shippinEstiConfi){
		
		$yaml = new Parser();
		$this->fedexConfig = $yaml->parse(file_get_contents(__DIR__.'/../Resources/config/fedex_config_param.yml'));
		$this->environment = $this->fedexConfig['parameters']['environment'];
		$this->accountNumber = $this->fedexConfig['parameters']['account_number_'.$this -> environment];
		$this->meterNumber = $this->fedexConfig['parameters']['meter_number_'.$this -> environment];
		$this->accessKey = $this->fedexConfig['parameters']['access_key_'.$this -> environment];
		$this->accessKeyPassword = $this->fedexConfig['parameters']['access_key_password_'.$this -> environment];
		$this-> accountCountry = $this->fedexConfig['parameters']['access_country_'.$this -> environment];
		$this->type = $type;
		if($type=='rate')
		{
			$this->allParameter = $this->fedexConfig['parameters']['rate'];
			$this->pathWsdl=$this->fedexConfig['parameters']['wsdl_file_path'].$this->allParameter['wsdl_file'];
			$this->dropOffType = $shippinEstiConfi['dropoff_type']['status'];
			$this->packingType = $shippinEstiConfi['packing_type']['status'];
			$this->paymentType= $shippinEstiConfi['payment_type']['status'];
			$this->rateRequestType= $shippinEstiConfi['rate_request_type']['status'];			
			$this->packageCount = 0;
			$this->service = '\FedEx\RateService';
		}
		if($type=='ship')
		{
			$this->allParameter = $this->fedexConfig['parameters']['ship'];
			$this->service = '\FedEx\ShipService';
			$this->dropOffType = $shippinEstiConfi['dropoff_type']['status'];
			$this->packingType = $shippinEstiConfi['packing_type']['status'];
			
			$this->imageType = $shippinEstiConfi['label_doc_image_type']['status'];
			$this->labelFormat = $shippinEstiConfi['label_format_type']['status'];
			$this->stockType = $shippinEstiConfi['label_stock_type']['status'];
			
			$this->paymentType= $shippinEstiConfi['payment_type']['status'];
			$this->rateRequestType= $shippinEstiConfi['rate_request_type']['status'];
		}
		if($type=='track')
		{
			$this->allParameter = $this->fedexConfig['parameters']['track'];
			$this->service = '\FedEx\TrackService';
			
		}
		//$this->rateRequest = new ComplexType\RateRequest();
	}
	
	
	public function setAuthenticationDetail()
	{
		$webAuthenticationCredential=$this->service.'\ComplexType\WebAuthenticationCredential';
		$userCredential = new $webAuthenticationCredential;
		
		$userCredential
		->setKey($this -> accessKey)
		->setPassword($this -> accessKeyPassword);
		
		$webAuthenticationDetail=$this->service.'\ComplexType\WebAuthenticationDetail';
		$webAuthenticationDetail = new $webAuthenticationDetail;
		$webAuthenticationDetail->setUserCredential($userCredential);
		return $webAuthenticationDetail;
	}
	
	public function setClientDetail()
	{
		$clientDetail=$this->service.'\ComplexType\ClientDetail';
		$clientDetail = new $clientDetail;
		//$clientDetail = new ComplexType\ClientDetail();
		$clientDetail
		->setAccountNumber($this->accountNumber)
		->setMeterNumber($this -> meterNumber);
		//$this->rateRequest -> setClientDetail($clientDetail);
		return $clientDetail;
	}
	
	public function setTransaction()
	{
		$TransactionDetail=$this->service.'\ComplexType\TransactionDetail';
		$transactionDetail = new $TransactionDetail;
		//$transactionDetail = new ComplexType\TransactionDetail();
		$transactionDetail->setCustomerTransactionId('');
		return $transactionDetail;
		//$this->rateRequest->setTransactionDetail($transactionDetail);
	}
	
	public function setVersionDetail()
	{
		$VersionId=$this->service.'\ComplexType\VersionId';
		$version = new $VersionId;
		//$version = new ComplexType\VersionId();
		$version
		->setServiceId($this->allParameter['version']['ServiceId'])
		->setMajor($this->allParameter['version']['Major'])
		->setIntermediate($this->allParameter['version']['Intermediate'])
		->setMinor($this->allParameter['version']['Minor']);
		//$this->rateRequest->setVersion($version);
		return $version;
	}
	
	public function setShipper($shipperDetail)
	{
		//RequestedShipment/Shipper
		$Address=$this->service.'\ComplexType\Address';
		$shipperAddress = new $Address;
		//$shipperAddress = new ComplexType\Address();
		
		$shipperAddress
		//->setStreetLines($shipperDetail['shipperAdd'])
		->setCity($shipperDetail['shipperCity'])
		->setStateOrProvinceCode($shipperDetail['shipperState'])
		->setPostalCode($shipperDetail['shipperZip'])
		->setCountryCode($shipperDetail['shipperCountry']);
		
		$ShipperContact=$this->service.'\ComplexType\Contact';
		$shipperContact = new $ShipperContact;
		$shipperContact
		->setCompanyName($shipperDetail['shipperCompanyName'])
		->setEMailAddress($shipperDetail['shipperEmail'])
		->setPersonName($shipperDetail['shipperName'])
		->setPhoneNumber($shipperDetail['shipperPhone']);
		
		$Party=$this->service.'\ComplexType\Party';
		$shipper = new $Party;
		//$shipper = new ComplexType\Party();
		$shipper->setAccountNumber($this->accountNumber);
		$shipper->setAddress($shipperAddress);
		if($this->type=='ship')
		{
			$shipper->setContact($shipperContact);
		}
		$this->requestedShipment->setShipper($shipper);
	}
	
	public function setRecipient($userDetail)
	{
		 
		//RequestedShipment/Recipient
		$Address=$this->service.'\ComplexType\Address';
		$recipientAddress = new $Address;
		//$recipientAddress = new ComplexType\Address();
		
		if($this->type=='ship')
		{
			$recipientAddress->setStreetLines($userDetail['userAdd']);
			$recipientAddress->setCity($userDetail['userCity']);
		}
		$recipientAddress->setStateOrProvinceCode($userDetail['userState'])
		->setPostalCode($userDetail['userZip'])
		->setCountryCode($userDetail['userCountry'])
		->setResidential($userDetail['userIsResident']);

		if($this->type=='ship')
		{
			$RecipientContact=$this->service.'\ComplexType\Contact';
			$recipientContact = new $RecipientContact;
			$recipientContact
			->setPersonName($userDetail['userName'])
			->setPhoneNumber($userDetail['userPhone']);
		}
		
		$Party=$this->service.'\ComplexType\Party';
		$recipient = new $Party;
		//$recipient = new ComplexType\Party();
		$recipient->setAddress($recipientAddress);
		
		if($this->type=='ship')
		{
			$recipient->setContact($recipientContact);
			$recipient->setAccountNumber($this->accountNumber);
		}
		
		
		$this->requestedShipment->setRecipient($recipient);
	}
	
	public function setShippingchargesPayment()
	{
		//RequestedShipment/ShippingChargesPayment
		$Payment=$this->service.'\ComplexType\Payment';
		$shippingChargesPayment = new $Payment;
		
		$PaymentType=$this->service.'\SimpleType\PaymentType';
		$paymentType = new $PaymentType($this->paymentType);
		
		$RateRequestType=$this->service.'\SimpleType\RateRequestType';
		$rateRequestType = new $RateRequestType($this->rateRequestType);

		$shippingChargesPayment->setPaymentType( new $PaymentType($this->paymentType));
		
		$Payor=$this->service.'\ComplexType\Payor';
		$payor = new $Payor;
	
		$payor->setAccountNumber($this->accountNumber);
		$payor->setCountryCode($this->accountCountry);
		$shippingChargesPayment->setPayor($payor);
		$this->requestedShipment->setShippingChargesPayment($shippingChargesPayment);
		//RequestedShipment\RateRequestTypes
		
		// to get register user fedex rate means your rate and public rate of fedex then use _LIST and if want to use public amount then use _ACCOUNT
		// right now coding is as per your rate means _LIST
		$this->requestedShipment->setRateRequestTypes(array(
				#new SimpleType\RateRequestType(SimpleType\RateRequestType::_ACCOUNT),
				//new SimpleType\RateRequestType(SimpleType\RateRequestType::_LIST)
				new $rateRequestType(($this->rateRequestType))
		));
	}
	
	
	public function setShipShippingchargesPayment($shipperDetail)
	{
		$Address=$this->service.'\ComplexType\Address';
		$shipperAddress = new $Address;
		$shipperAddress
		->setStreetLines($shipperDetail['shipperAdd'])
		->setCity($shipperDetail['shipperCity'])
		->setStateOrProvinceCode($shipperDetail['shipperState'])
		->setPostalCode($shipperDetail['shipperZip'])
		->setCountryCode($shipperDetail['shipperCountry']);
		
		$ShipperContact=$this->service.'\ComplexType\Contact';
		$shipperContact = new $ShipperContact;
		$shipperContact
		->setCompanyName($shipperDetail['shipperCompanyName'])
		->setEMailAddress($shipperDetail['shipperEmail'])
		->setPersonName($shipperDetail['shipperName'])
		->setPhoneNumber($shipperDetail['shipperPhone']);
			
		$Payment=$this->service.'\ComplexType\Payment';
		$shippingChargesPayment = new $Payment;
			
		$Party=$this->service.'\ComplexType\Party';
		$shipper = new $Party;
		$shipper->setAddress($shipperAddress)
		->setAccountNumber($this->accountNumber)
		->setContact($shipperContact);
			
		$Payor=$this->service.'\ComplexType\Payor';
		$payor = new $Payor;
		$payor->setResponsibleParty($shipper);
			
		$PaymentType=$this->service.'\SimpleType\PaymentType';
		$paymentType = new $PaymentType($this->paymentType);
		
		$shippingChargesPayment
		->setPaymentType($paymentType)
		->setPayor($payor);
		
		$RateRequestType=$this->service.'\SimpleType\RateRequestType';
		$rateRequestType = new $RateRequestType($this->rateRequestType);
		
		$this->requestedShipment->setRateRequestTypes(array(
				new $rateRequestType(($this->rateRequestType))
		));
		
		$this->requestedShipment->setShippingChargesPayment($shippingChargesPayment);
	}
	
	public function setPackageCount($noOfBox)
	{//RequestedShipment\PackageCount
		$this->packageCount=$noOfBox;
		//$this->packageCount=$noOfBox; for static
		$this->requestedShipment->setPackageCount($noOfBox);
	}
	
	//RequestedShipment
	public function setShipmentDetail($shippingEstiDetail){
		
		$RequestedShipment=$this->service.'\ComplexType\RequestedShipment';
		$this->requestedShipment = new $RequestedShipment;
		
		
		//RequestedShipment/DropoffType
		//$this->requestedShipment->setDropoffType(SimpleType\DropoffType::_DROP_BOX);
		//$this->requestedShipment->setPackagingType(SimpleType\PackagingType::_YOUR_PACKAGING);
		
		$this->requestedShipment->setDropoffType($this->dropOffType);
		$this->requestedShipment->setPackagingType($this->packingType);
		if($this->type=='ship')
		{
			$this->requestedShipment->setServiceType($shippingEstiDetail['serviceType']);
		}
	
		//RequestedShipment/Shiptimestamp
		$this->requestedShipment->setShipTimestamp(date('c'));
		
		$cartonHeight = $shippingEstiDetail['cartonHeight'];
		$cartonLength= $shippingEstiDetail['cartonLength'];
		$cartonWidth= $shippingEstiDetail['cartonWidth'];
		$cartonWeight= $shippingEstiDetail['cartonWeight'];
		
		
		//for static data
		/*$cartonHeight = 0;
		$cartonLength= 0;
		$cartonWidth=  0;
		$cartonWeight= 0;*/
		
		
		$qtyPerCartoon= $shippingEstiDetail['qtyPerCartoon'];
		$productWeight= $shippingEstiDetail['productWeight'];
		$weightArray= $shippingEstiDetail['totalWeight'];
		
		$noOfBox= $shippingEstiDetail['noOfBox'];
		
		$shipperState= $shippingEstiDetail['state'];
		$shipperZip= $shippingEstiDetail['zipcode'];
		$shipperCountry= $shippingEstiDetail['country'];
		
		//$userDetail=array('userAdd'=>$shippingEstiDetail['reciver']['userAdd'],'userCity'=>$shippingEstiDetail['reciver']['userCity'],'userState'=>$shippingEstiDetail['reciver']['userState'] ,'userZip'=>$shippingEstiDetail['reciver']['userZip'], 'userCountry' =>$shippingEstiDetail['reciver']['userCountry'] );
		
		$this->setShipper($shippingEstiDetail['shipper']);
		
		$this->setRecipient($shippingEstiDetail['reciver']);
		
		if($this->type=='ship')
		{
			$this->setShipShippingchargesPayment($shippingEstiDetail['shipper']);
		}
		else
		{
			$this->setShippingchargesPayment();
		}
		$this->setPackageCount($noOfBox);
		$this->setPackageLineItem($weightArray,$cartonHeight,$cartonLength,$cartonWidth);
		return $this->requestedShipment;
	}
	
	public function setPackageLineItem($weight,$carton_height,$carton_length,$carton_width)
	{
		
		//RequestedShipment\RequestedPackageLineItems
		$lineItems = array();
		for($i=0;$i<$this->packageCount;$i++)   // remove for static
		{
			$j=1;
			$Weight=$this->service.'\ComplexType\Weight';
			$itemWeight = new $Weight;
			
			$WeightUnits=$this->service.'\SimpleType\WeightUnits';
			$weightUnits = new $WeightUnits($WeightUnits::_LB);
			
			$RequestedPackageLineItem=$this->service.'\ComplexType\RequestedPackageLineItem';
			$item = new $RequestedPackageLineItem;
			
			$itemWeight
			->setUnits($weightUnits)
			->setValue($weight[$i]);
			// ->setValue($weight);  // for static data

			if($carton_height!=0 && $carton_length!=0 && $carton_width!=0)
			{
				$Dimensions=$this->service.'\ComplexType\Dimensions';
				$itemDimensions = new $Dimensions;
				
				$LinearUnits=$this->service.'\SimpleType\LinearUnits';
				$linearUnits = new $LinearUnits($LinearUnits::_IN);
				
				$itemDimensions
				->setLength($carton_width)
				->setWidth($carton_length)
				->setHeight($carton_height)
				->setUnits($linearUnits);
				$item->setDimensions($itemDimensions);
			}
		
			$item->setWeight($itemWeight);
		
			$item->setGroupPackageCount($j);
			$j++;
			//$item->setGroupPackageCount(1);
			$lineItems[] = $item;
			
		}
		$this->requestedShipment->setRequestedPackageLineItems($lineItems);
	}
}


?>