<?php
/**
* @filename        CanadaPost.php
* @description     This class is for Canada Post
* @version         1.0
* @package         MSHShippingLibrary.shippingClasses
* @author          Mohammad Sajjad Hossain - info@sajjadhossain.com
*
* @link            http://sajjadhossain.com
* @created on      December 27, 2010
* @Dependencies
* @license
***/

class CanadaPost extends Carrier
{
    public function CanadaPost()
    {
        parent::Carrier();
        $this->setRequestUrl('http://sellonline.canadapost.ca:30000');
        $this->setDefaultUserId('CPC_DEMO_XML');
        $this->setCacheTableSuffix('canpost');
        $this->disableCache();
    }

    public function calculate()
    {
        $this->logMessage('Validating Information for Canada Post');
        $this->validateServiceSelected();
        $this->validateFromState();
        $this->validateFromZip();
        $this->validateFromCountyCode('CA');
        $this->validateToCity();
        $this->validateToState();
        $this->validateToZip();
        $this->validateToCountyCode();

        if($this->isValid())
        {
            $this->setParam('XMLRequest', $this->getXML());
            $this->makeAPICall();
        }

        return $this->response;
    }

    protected function getSearchString()
    {
        $this->searchString = $this->getUserId() . ':'
                                . $this->getFromZip() . ':'
                                . $this->item->getQuantity() . ':'
                                . $this->item->getWeightInKilogram() . ':'
                                . $this->item->getLengthInCentimeter() . ':'
                                . $this->item->getWidthInCentimeter() . ':'
                                . $this->item->getHeightInCentimeter() . ':'
                                . $this->getWeightUnit() . ':'
                                . $this->getLengthUnit() . ':';

        if(in_array($this->getToCountryCode(), array('US', 'CA')))
        {
            $this->searchString .= $this->getToState() . ':'
                                    . $this->getToCountry() . ':'
                                    . $this->getToZip();
        }
        else
        {
            $this->searchString .= $this->getToCountry();
        }

        return $this->searchString;
    }

    private function getXML()
    {
        if(!empty($this->item))
        {
            $this->item->validate(array('quantity', 'weight', 'length', 'height', 'width'));

            $xml = '<?xml version="1.0" ?>
                <eparcel>
                    <language>en</language>
                    <ratesAndServicesRequest>
                        <merchantCPCID>' . $this->getUserId() . '</merchantCPCID>
                        <fromPostalCode>' . $this->getFromZip() . '</fromPostalCode>
                        <turnAroundTime>24</turnAroundTime>
                        <lineItems>
                            <item>
                                <quantity>' . $this->item->getQuantity() . '</quantity>
                                <weight>' . $this->item->getWeightInKilogram() . '</weight>
                                <length>' . $this->item->getLengthInCentimeter() . '</length>
                                <width>' . $this->item->getWidthInCentimeter() . '</width>
                                <height>' . $this->item->getHeightInCentimeter() . '</height>
                                <description>' . $this->convertForXML($this->item->getDescription()) . '</description>
                            </item>
                        </lineItems>
                        <city>' . $this->getToCity() . '</city>
                        <provOrState>' . $this->getToState() . '</provOrState>
                        <country>' . $this->getToCountry() . '</country>
                        <postalCode>' . $this->getToZip() . '</postalCode>
                    </ratesAndServicesRequest>
                </eparcel>';
            return $xml;
        }
        else
        {
            $this->response->setError('No items has been added');
            return '';
        }
    }

    protected function prepareResponse()
    {
        $rawResponse = $this->response->getRawResponse();

        $obj = simplexml_load_string($rawResponse);

        $objStatus = $obj->xpath('/eparcel/ratesAndServicesResponse/statusCode');

        $status = 0;

        if($objStatus)
        {
            while(list(,$node) = each($objStatus))
            {
                $status = $node;
            }
        }

        if($status)
        {
            $rates = $obj->xpath('/eparcel/ratesAndServicesResponse/product');

            if($rates)
            {
                foreach($rates as $rate)
                {
                    $rate = (array) $rate;

                    if(in_array($rate['name'], $this->getServices()))
                    {
                        $this->response->setRate($rate['name'], $rate['rate']);
                    }
                }

                $rates = $this->response->getRates();

                if(!empty($rates))
                {
                    $this->insertResponseToDB();
                }
            }
        }
        else
        {
            $objError = $obj->xpath('/eparcel/error/statusMessage');

            if($objError)
            {
                while(list(,$node) = each($objError))
                {
                    $node = (array) $node;
                    $this->response->setError($node[0]);
                }
            }
        }
    }
}
//End of file CanadaPost.php