/**
* Calculates the value of the fedex shipping modifier. If the order information has changed or is not present in the session a call is made to the api to request the rates.
* @return {float} Cost of the shipping
*/
public function value($subtotal = 0)
{
if ($this->Order()->Items()->count() == 0) {
return 0;
}
$orderItems = implode(',', $this->Order()->Items()->column('ID'));
$orderItemsCount = implode(',', $this->Order()->Items()->column('Quantity'));
$shippingAddress = array();
$shippingAddressStr = '';
if ($this->Order()) {
if ($this->Order()->ShippingAddress && $this->Order()->ShippingAddress->exists()) {
$destination = $this->Order()->ShippingAddress;
$shippingAddress = array('StreetLines' => array($destination->Address), 'City' => $destination->City, 'StateOrProvinceCode' => $destination->State, 'PostalCode' => $destination->PostalCode, 'CountryCode' => $destination->Country);
$addrLine2 = $destination->AddressLine2;
$shippingAddressStr = $shippingAddress;
$shippingAddressStr['StreetLines'] = implode(' ', $shippingAddressStr['StreetLines']);
$shippingAddressStr = implode(',', $shippingAddressStr);
} else {
if ($this->Order()->Member()->DefaultShippingAddress() && $this->Order()->Member()->DefaultShippingAddress()->exists()) {
$destination = $this->Order()->Member()->DefaultShippingAddress();
$shippingAddress = array('StreetLines' => array($destination->Address), 'City' => $destination->City, 'StateOrProvinceCode' => $destination->State, 'PostalCode' => $destination->PostalCode, 'CountryCode' => $destination->Country);
$addrLine2 = $destination->AddressLine2;
$shippingAddressStr = $shippingAddress;
$shippingAddressStr['StreetLines'] = implode(' ', $shippingAddressStr['StreetLines']);
$shippingAddressStr = implode(',', $shippingAddressStr);
}
}
}
if ($this->Amount > 0 && $orderItems . '|' . $orderItemsCount . '|' . $shippingAddressStr == Session::get('FedExShipping_' . $this->Order()->ID . '.orderhash')) {
return $this->Amount;
}
//Store the default charge in case something goes wrong
$this->Amount = self::config()->default_charge;
if (!isset($destination)) {
return $this->Amount;
}
$packageItems = array();
foreach ($this->Order()->Items() as $item) {
if ($item instanceof Product_OrderItem) {
$packageItems[] = new ComplexType\RequestedPackageLineItem(array('Weight' => new ComplexType\Weight(array('Units' => new SimpleType\WeightUnits(SimpleType\WeightUnits::_KG), 'Value' => $item->Product()->Weight)), 'Dimensions' => new ComplexType\Dimensions(array('Length' => $item->Product()->Depth, 'Width' => $item->Product()->Width, 'Height' => $item->Product()->Height, 'Units' => new SimpleType\LinearUnits(SimpleType\LinearUnits::_CM))), 'GroupPackageCount' => $item->Quantity));
}
}
$rateRequest = $this->getRateRequestAPI();
//RequestedShipment
$rateRequest->setRequestedShipment(new ComplexType\RequestedShipment(array('DropoffType' => new SimpleType\DropoffType(SimpleType\DropoffType::_REGULAR_PICKUP), 'ShipTimestamp' => date('c'), 'Shipper' => new ComplexType\Party(array('Address' => new ComplexType\Address($this->getOriginAddress()))), 'Recipient' => new ComplexType\Party(array('Address' => new ComplexType\Address($shippingAddress))), 'PreferredCurrency' => ShopConfig::config()->base_currency, 'RateRequestType' => new SimpleType\RateRequestType(SimpleType\RateRequestType::_LIST), 'PackageCount' => $this->Order()->Items()->count(), 'RequestedPackageLineItems' => $packageItems)));
//Allow extensions to modify the
$this->extend('updateRateRequest', $rateRequest);
//Initialize the request
$validateShipmentRequest = new RateService\Request();
if (!$this->config()->test_mode) {
$validateShipmentRequest->getSoapClient()->__setLocation('https://ws.fedex.com:443/web-services/rate');
}
//Call the api and look through the response
$response = $validateShipmentRequest->getGetRatesReply($rateRequest);
if (property_exists($response, 'RateReplyDetails') && count($response->RateReplyDetails) > 0) {
foreach ($response->RateReplyDetails as $rates) {
if ($rates->ServiceType == self::config()->service_type) {
foreach ($rates->RatedShipmentDetails as $rate) {
if (property_exists($rate, 'TotalNetCharge')) {
$charge = $rate->TotalNetCharge;
if ($charge->Currency != ShopConfig::get_base_currency() && property_exists($rate, 'CurrencyExchangeRate')) {
$charge->Amount = (1 - $rate->CurrencyExchangeRate->Rate + 1) * $charge->Amount;
}
$this->Amount = $charge->Amount;
}
}
}
}
}
Session::set('FedExShipping_' . $this->Order()->ID . '.orderhash', $orderItems . '|' . $orderItemsCount . '|' . $shippingAddressStr);
return $this->Amount;
}