Overview

Packages

  • currencysymbol
  • MAbout
  • Mage
    • Admin
    • Adminhtml
    • AdminNotification
    • Api
    • Api2
    • Authorizenet
    • Backup
    • Bundle
    • Captcha
    • Catalog
    • CatalogIndex
    • CatalogInventory
    • CatalogRule
    • CatalogSearch
    • Centinel
    • Checkout
    • Cms
    • Compiler
    • Connect
    • Contacts
    • Core
    • Cron
    • CurrencySymbol
    • Customer
    • Dataflow
    • Directory
    • DirtectPost
    • Downloadable
    • Eav
    • GiftMessage
    • GoogleAnalytics
    • GoogleBase
    • GoogleCheckout
    • ImportExport
    • Index
    • Install
    • Log
    • Media
    • Newsletter
    • Oauth
    • Page
    • PageCache
    • Paygate
    • Payment
    • Paypal
    • PaypalUk
    • Persistent
    • Poll
    • ProductAlert
    • Rating
    • Reports
    • Review
    • Rss
    • Rule
    • Sales
    • SalesRule
    • Sedfriend
    • Sendfriend
    • Shipping
    • Sitemap
    • Tag
    • Tax
    • Usa
    • Weee
    • Widget
    • Wishlist
    • XmlConnect
  • None
  • Phoenix
    • Moneybookers
  • PHP
  • Zend
    • Date
    • Mime
    • XmlRpc

Classes

  • Mage_Shipping_Block_Tracking_Ajax
  • Mage_Shipping_Block_Tracking_Popup
  • Mage_Shipping_Exception
  • Mage_Shipping_Helper_Data
  • Mage_Shipping_Model_Carrier_Abstract
  • Mage_Shipping_Model_Carrier_Flatrate
  • Mage_Shipping_Model_Carrier_Freeshipping
  • Mage_Shipping_Model_Carrier_Pickup
  • Mage_Shipping_Model_Carrier_Tablerate
  • Mage_Shipping_Model_Config
  • Mage_Shipping_Model_Info
  • Mage_Shipping_Model_Mysql4_Carrier_Tablerate
  • Mage_Shipping_Model_Mysql4_Carrier_Tablerate_Collection
  • Mage_Shipping_Model_Rate_Abstract
  • Mage_Shipping_Model_Rate_Request
  • Mage_Shipping_Model_Rate_Result
  • Mage_Shipping_Model_Rate_Result_Abstract
  • Mage_Shipping_Model_Rate_Result_Error
  • Mage_Shipping_Model_Rate_Result_Method
  • Mage_Shipping_Model_Resource_Carrier_Tablerate
  • Mage_Shipping_Model_Resource_Carrier_Tablerate_Collection
  • Mage_Shipping_Model_Shipment_Request
  • Mage_Shipping_Model_Shipment_Return
  • Mage_Shipping_Model_Shipping
  • Mage_Shipping_Model_Source_HandlingAction
  • Mage_Shipping_Model_Source_HandlingType
  • Mage_Shipping_Model_Tracking_Result
  • Mage_Shipping_Model_Tracking_Result_Abstract
  • Mage_Shipping_Model_Tracking_Result_Error
  • Mage_Shipping_Model_Tracking_Result_Status

Interfaces

  • Mage_Shipping_Model_Carrier_Interface
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Magento
  4:  *
  5:  * NOTICE OF LICENSE
  6:  *
  7:  * This source file is subject to the Open Software License (OSL 3.0)
  8:  * that is bundled with this package in the file LICENSE.txt.
  9:  * It is also available through the world-wide-web at this URL:
 10:  * http://opensource.org/licenses/osl-3.0.php
 11:  * If you did not receive a copy of the license and are unable to
 12:  * obtain it through the world-wide-web, please send an email
 13:  * to license@magentocommerce.com so we can send you a copy immediately.
 14:  *
 15:  * DISCLAIMER
 16:  *
 17:  * Do not edit or add to this file if you wish to upgrade Magento to newer
 18:  * versions in the future. If you wish to customize Magento for your
 19:  * needs please refer to http://www.magentocommerce.com for more information.
 20:  *
 21:  * @category    Mage
 22:  * @package     Mage_Shipping
 23:  * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
 24:  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 25:  */
 26: 
 27: 
 28: class Mage_Shipping_Model_Shipping
 29: {
 30:     /**
 31:      * Store address
 32:      */
 33:     const XML_PATH_STORE_ADDRESS1     = 'shipping/origin/street_line1';
 34:     const XML_PATH_STORE_ADDRESS2     = 'shipping/origin/street_line2';
 35:     const XML_PATH_STORE_CITY         = 'shipping/origin/city';
 36:     const XML_PATH_STORE_REGION_ID    = 'shipping/origin/region_id';
 37:     const XML_PATH_STORE_ZIP          = 'shipping/origin/postcode';
 38:     const XML_PATH_STORE_COUNTRY_ID   = 'shipping/origin/country_id';
 39: 
 40:     /**
 41:      * Default shipping orig for requests
 42:      *
 43:      * @var array
 44:      */
 45:     protected $_orig = null;
 46: 
 47:     /**
 48:      * Cached result
 49:      *
 50:      * @var Mage_Sales_Model_Shipping_Method_Result
 51:      */
 52:     protected $_result = null;
 53: 
 54:     /**
 55:      * Part of carrier xml config path
 56:      *
 57:      * @var string
 58:      */
 59:     protected $_availabilityConfigField = 'active';
 60: 
 61:     /**
 62:      * Get shipping rate result model
 63:      *
 64:      * @return Mage_Shipping_Model_Rate_Result
 65:      */
 66:     public function getResult()
 67:     {
 68:         if (empty($this->_result)) {
 69:             $this->_result = Mage::getModel('shipping/rate_result');
 70:         }
 71:         return $this->_result;
 72:     }
 73: 
 74:     /**
 75:      * Set shipping orig data
 76:      *
 77:      * @param array $data
 78:      * @return null
 79:      */
 80:     public function setOrigData($data)
 81:     {
 82:         $this->_orig = $data;
 83:     }
 84: 
 85:     /**
 86:      * Reset cached result
 87:      *
 88:      * @return Mage_Shipping_Model_Shipping
 89:      */
 90:     public function resetResult()
 91:     {
 92:         $this->getResult()->reset();
 93:         return $this;
 94:     }
 95: 
 96:     /**
 97:      * Retrieve configuration model
 98:      *
 99:      * @return Mage_Shipping_Model_Config
100:      */
101:     public function getConfig()
102:     {
103:         return Mage::getSingleton('shipping/config');
104:     }
105: 
106:     /**
107:      * Retrieve all methods for supplied shipping data
108:      *
109:      * @todo make it ordered
110:      * @param Mage_Shipping_Model_Shipping_Method_Request $data
111:      * @return Mage_Shipping_Model_Shipping
112:      */
113:     public function collectRates(Mage_Shipping_Model_Rate_Request $request)
114:     {
115:         $storeId = $request->getStoreId();
116:         if (!$request->getOrig()) {
117:             $request
118:                 ->setCountryId(Mage::getStoreConfig(self::XML_PATH_STORE_COUNTRY_ID, $request->getStore()))
119:                 ->setRegionId(Mage::getStoreConfig(self::XML_PATH_STORE_REGION_ID, $request->getStore()))
120:                 ->setCity(Mage::getStoreConfig(self::XML_PATH_STORE_CITY, $request->getStore()))
121:                 ->setPostcode(Mage::getStoreConfig(self::XML_PATH_STORE_ZIP, $request->getStore()));
122:         }
123: 
124:         $limitCarrier = $request->getLimitCarrier();
125:         if (!$limitCarrier) {
126:             $carriers = Mage::getStoreConfig('carriers', $storeId);
127: 
128:             foreach ($carriers as $carrierCode => $carrierConfig) {
129:                 $this->collectCarrierRates($carrierCode, $request);
130:             }
131:         } else {
132:             if (!is_array($limitCarrier)) {
133:                 $limitCarrier = array($limitCarrier);
134:             }
135:             foreach ($limitCarrier as $carrierCode) {
136:                 $carrierConfig = Mage::getStoreConfig('carriers/' . $carrierCode, $storeId);
137:                 if (!$carrierConfig) {
138:                     continue;
139:                 }
140:                 $this->collectCarrierRates($carrierCode, $request);
141:             }
142:         }
143: 
144:         return $this;
145:     }
146: 
147:     /**
148:      * Collect rates of given carrier
149:      *
150:      * @param string                           $carrierCode
151:      * @param Mage_Shipping_Model_Rate_Request $request
152:      * @return Mage_Shipping_Model_Shipping
153:      */
154:     public function collectCarrierRates($carrierCode, $request)
155:     {
156:         /* @var $carrier Mage_Shipping_Model_Carrier_Abstract */
157:         $carrier = $this->getCarrierByCode($carrierCode, $request->getStoreId());
158:         if (!$carrier) {
159:             return $this;
160:         }
161:         $carrier->setActiveFlag($this->_availabilityConfigField);
162:         $result = $carrier->checkAvailableShipCountries($request);
163:         if (false !== $result && !($result instanceof Mage_Shipping_Model_Rate_Result_Error)) {
164:             $result = $carrier->proccessAdditionalValidation($request);
165:         }
166:         /*
167:         * Result will be false if the admin set not to show the shipping module
168:         * if the delivery country is not within specific countries
169:         */
170:         if (false !== $result){
171:             if (!$result instanceof Mage_Shipping_Model_Rate_Result_Error) {
172:                 if ($carrier->getConfigData('shipment_requesttype')) {
173:                     $packages = $this->composePackagesForCarrier($carrier, $request);
174:                     if (!empty($packages)) {
175:                         $sumResults = array();
176:                         foreach ($packages as $weight => $packageCount) {
177:                             $request->setPackageWeight($weight);
178:                             $result = $carrier->collectRates($request);
179:                             if (!$result) {
180:                                 return $this;
181:                             } else {
182:                                 $result->updateRatePrice($packageCount);
183:                             }
184:                             $sumResults[] = $result;
185:                         }
186:                         if (!empty($sumResults) && count($sumResults) > 1) {
187:                             $result = array();
188:                             foreach ($sumResults as $res) {
189:                                 if (empty($result)) {
190:                                     $result = $res;
191:                                     continue;
192:                                 }
193:                                 foreach ($res->getAllRates() as $method) {
194:                                     foreach ($result->getAllRates() as $resultMethod) {
195:                                         if ($method->getMethod() == $resultMethod->getMethod()) {
196:                                             $resultMethod->setPrice($method->getPrice() + $resultMethod->getPrice());
197:                                             continue;
198:                                         }
199:                                     }
200:                                 }
201:                             }
202:                         }
203:                     } else {
204:                         $result = $carrier->collectRates($request);
205:                     }
206:                 } else {
207:                     $result = $carrier->collectRates($request);
208:                 }
209:                 if (!$result) {
210:                     return $this;
211:                 }
212:             }
213:             if ($carrier->getConfigData('showmethod') == 0 && $result->getError()) {
214:                 return $this;
215:             }
216:             // sort rates by price
217:             if (method_exists($result, 'sortRatesByPrice')) {
218:                 $result->sortRatesByPrice();
219:             }
220:             $this->getResult()->append($result);
221:         }
222:         return $this;
223:     }
224: 
225:     /**
226:      * Compose Packages For Carrier.
227:      * Devides order into items and items into parts if it's neccesary
228:      *
229:      * @param Mage_Shipping_Model_Carrier_Abstract $carrier
230:      * @param Mage_Shipping_Model_Rate_Request $request
231:      * @return array [int, float]
232:      */
233:     public function composePackagesForCarrier($carrier, $request)
234:     {
235:         $allItems   = $request->getAllItems();
236:         $fullItems  = array();
237: 
238:         $maxWeight  = (float) $carrier->getConfigData('max_package_weight');
239: 
240:         foreach ($allItems as $item) {
241:             if ($item->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
242:                 && $item->getProduct()->getShipmentType()
243:             ) {
244:                 continue;
245:             }
246: 
247:             $qty            = $item->getQty();
248:             $changeQty      = true;
249:             $checkWeight    = true;
250:             $decimalItems   = array();
251: 
252:             if ($item->getParentItem()) {
253:                 if (!$item->getParentItem()->getProduct()->getShipmentType()) {
254:                     continue;
255:                 }
256:                 $qty = $item->getIsQtyDecimal()
257:                     ? $item->getParentItem()->getQty()
258:                     : $item->getParentItem()->getQty() * $item->getQty();
259:             }
260: 
261:             $itemWeight = $item->getWeight();
262:             if ($item->getIsQtyDecimal() && $item->getProductType() != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
263:                 $stockItem = $item->getProduct()->getStockItem();
264:                 if ($stockItem->getIsDecimalDivided()) {
265:                    if ($stockItem->getEnableQtyIncrements() && $stockItem->getQtyIncrements()) {
266:                         $itemWeight = $itemWeight * $stockItem->getQtyIncrements();
267:                         $qty        = round(($item->getWeight() / $itemWeight) * $qty);
268:                         $changeQty  = false;
269:                    } else {
270:                        $itemWeight = $itemWeight * $item->getQty();
271:                        if ($itemWeight > $maxWeight) {
272:                            $qtyItem = floor($itemWeight / $maxWeight);
273:                            $decimalItems[] = array('weight' => $maxWeight, 'qty' => $qtyItem);
274:                            $weightItem = Mage::helper('core')->getExactDivision($itemWeight, $maxWeight);
275:                            if ($weightItem) {
276:                                $decimalItems[] = array('weight' => $weightItem, 'qty' => 1);
277:                            }
278:                            $checkWeight = false;
279:                        } else {
280:                            $itemWeight = $itemWeight * $item->getQty();
281:                        }
282:                    }
283:                 } else {
284:                     $itemWeight = $itemWeight * $item->getQty();
285:                 }
286:             }
287: 
288:             if ($checkWeight && $maxWeight && $itemWeight > $maxWeight) {
289:                 return array();
290:             }
291: 
292:             if ($changeQty && !$item->getParentItem() && $item->getIsQtyDecimal()
293:                 && $item->getProductType() != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
294:             ) {
295:                 $qty = 1;
296:             }
297: 
298:             if (!empty($decimalItems)) {
299:                 foreach ($decimalItems as $decimalItem) {
300:                     $fullItems = array_merge($fullItems,
301:                         array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight'])
302:                     );
303:                 }
304:             } else {
305:                 $fullItems = array_merge($fullItems, array_fill(0, $qty, $itemWeight));
306:             }
307:         }
308:         sort($fullItems);
309: 
310:         return $this->_makePieces($fullItems, $maxWeight);
311:     }
312: 
313:     /**
314:      * Make pieces
315:      * Compose packeges list based on given items, so that each package is as heavy as possible
316:      *
317:      * @param array $items
318:      * @param float $maxWeight
319:      * @return array
320:      */
321:     protected function _makePieces($items, $maxWeight)
322:     {
323:         $pieces = array();
324:         if (!empty($items)) {
325:             $sumWeight = 0;
326: 
327:             $reverseOrderItems = $items;
328:             arsort($reverseOrderItems);
329: 
330:             foreach ($reverseOrderItems as $key => $weight) {
331:                 if (!isset($items[$key])) {
332:                     continue;
333:                 }
334:                 unset($items[$key]);
335:                 $sumWeight = $weight;
336:                 foreach ($items as $key => $weight) {
337:                     if (($sumWeight + $weight) < $maxWeight) {
338:                         unset($items[$key]);
339:                         $sumWeight += $weight;
340:                     } elseif (($sumWeight + $weight) > $maxWeight) {
341:                         $pieces[] = (string)(float)$sumWeight;
342:                         break;
343:                     } else {
344:                         unset($items[$key]);
345:                         $pieces[] = (string)(float)($sumWeight + $weight);
346:                         $sumWeight = 0;
347:                         break;
348:                     }
349:                 }
350:             }
351:             if ($sumWeight > 0) {
352:                 $pieces[] = (string)(float)$sumWeight;
353:             }
354:             $pieces = array_count_values($pieces);
355:         }
356: 
357:         return $pieces;
358:     }
359: 
360:     /**
361:      * Collect rates by address
362:      *
363:      * @param Varien_Object $address
364:      * @param null|bool|array $limitCarrier
365:      * @return Mage_Shipping_Model_Shipping
366:      */
367:     public function collectRatesByAddress(Varien_Object $address, $limitCarrier = null)
368:     {
369:         /** @var $request Mage_Shipping_Model_Rate_Request */
370:         $request = Mage::getModel('shipping/rate_request');
371:         $request->setAllItems($address->getAllItems());
372:         $request->setDestCountryId($address->getCountryId());
373:         $request->setDestRegionId($address->getRegionId());
374:         $request->setDestPostcode($address->getPostcode());
375:         $request->setPackageValue($address->getBaseSubtotal());
376:         $request->setPackageValueWithDiscount($address->getBaseSubtotalWithDiscount());
377:         $request->setPackageWeight($address->getWeight());
378:         $request->setFreeMethodWeight($address->getFreeMethodWeight());
379:         $request->setPackageQty($address->getItemQty());
380:         $request->setStoreId(Mage::app()->getStore()->getId());
381:         $request->setWebsiteId(Mage::app()->getStore()->getWebsiteId());
382:         $request->setBaseCurrency(Mage::app()->getStore()->getBaseCurrency());
383:         $request->setPackageCurrency(Mage::app()->getStore()->getCurrentCurrency());
384:         $request->setLimitCarrier($limitCarrier);
385: 
386:         $request->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax());
387: 
388:         return $this->collectRates($request);
389:     }
390: 
391:     /**
392:      * Set part of carrier xml config path
393:      *
394:      * @param string $code
395:      * @return Mage_Shipping_Model_Shipping
396:      */
397:     public function setCarrierAvailabilityConfigField($code = 'active')
398:     {
399:         $this->_availabilityConfigField = $code;
400:         return $this;
401:     }
402: 
403:     /**
404:      * Get carrier by its code
405:      *
406:      * @param string $carrierCode
407:      * @param null|int $storeId
408:      * @return bool|Mage_Core_Model_Abstract
409:      */
410:     public function getCarrierByCode($carrierCode, $storeId = null)
411:     {
412:         if (!Mage::getStoreConfigFlag('carriers/'.$carrierCode.'/'.$this->_availabilityConfigField, $storeId)) {
413:             return false;
414:         }
415:         $className = Mage::getStoreConfig('carriers/'.$carrierCode.'/model', $storeId);
416:         if (!$className) {
417:             return false;
418:         }
419:         $obj = Mage::getModel($className);
420:         if ($storeId) {
421:             $obj->setStore($storeId);
422:         }
423:         return $obj;
424:     }
425: 
426:     /**
427:      * Prepare and do request to shipment
428:      *
429:      * @param Mage_Sales_Model_Order_Shipment $orderShipment
430:      * @return Varien_Object
431:      */
432:     public function requestToShipment(Mage_Sales_Model_Order_Shipment $orderShipment)
433:     {
434:         $admin = Mage::getSingleton('admin/session')->getUser();
435:         $order = $orderShipment->getOrder();
436:         $address = $order->getShippingAddress();
437:         $shippingMethod = $order->getShippingMethod(true);
438:         $shipmentStoreId = $orderShipment->getStoreId();
439:         $shipmentCarrier = $order->getShippingCarrier();
440:         $baseCurrencyCode = Mage::app()->getStore($shipmentStoreId)->getBaseCurrencyCode();
441:         if (!$shipmentCarrier) {
442:             Mage::throwException('Invalid carrier: ' . $shippingMethod->getCarrierCode());
443:         }
444:         $shipperRegionCode = Mage::getStoreConfig(self::XML_PATH_STORE_REGION_ID, $shipmentStoreId);
445:         if (is_numeric($shipperRegionCode)) {
446:             $shipperRegionCode = Mage::getModel('directory/region')->load($shipperRegionCode)->getCode();
447:         }
448: 
449:         $recipientRegionCode = Mage::getModel('directory/region')->load($address->getRegionId())->getCode();
450: 
451:         $originStreet1 = Mage::getStoreConfig(self::XML_PATH_STORE_ADDRESS1, $shipmentStoreId);
452:         $originStreet2 = Mage::getStoreConfig(self::XML_PATH_STORE_ADDRESS2, $shipmentStoreId);
453:         $storeInfo = new Varien_Object(Mage::getStoreConfig('general/store_information', $shipmentStoreId));
454: 
455:         if (!$admin->getFirstname() || !$admin->getLastname() || !$storeInfo->getName() || !$storeInfo->getPhone()
456:             || !$originStreet1 || !Mage::getStoreConfig(self::XML_PATH_STORE_CITY, $shipmentStoreId)
457:             || !$shipperRegionCode || !Mage::getStoreConfig(self::XML_PATH_STORE_ZIP, $shipmentStoreId)
458:             || !Mage::getStoreConfig(self::XML_PATH_STORE_COUNTRY_ID, $shipmentStoreId)
459:         ) {
460:             Mage::throwException(
461:                 Mage::helper('sales')->__('Insufficient information to create shipping label(s). Please verify your Store Information and Shipping Settings.')
462:             );
463:         }
464: 
465:         /** @var $request Mage_Shipping_Model_Shipment_Request */
466:         $request = Mage::getModel('shipping/shipment_request');
467:         $request->setOrderShipment($orderShipment);
468:         $request->setShipperContactPersonName($admin->getName());
469:         $request->setShipperContactPersonFirstName($admin->getFirstname());
470:         $request->setShipperContactPersonLastName($admin->getLastname());
471:         $request->setShipperContactCompanyName($storeInfo->getName());
472:         $request->setShipperContactPhoneNumber($storeInfo->getPhone());
473:         $request->setShipperEmail($admin->getEmail());
474:         $request->setShipperAddressStreet(trim($originStreet1 . ' ' . $originStreet2));
475:         $request->setShipperAddressStreet1($originStreet1);
476:         $request->setShipperAddressStreet2($originStreet2);
477:         $request->setShipperAddressCity(Mage::getStoreConfig(self::XML_PATH_STORE_CITY, $shipmentStoreId));
478:         $request->setShipperAddressStateOrProvinceCode($shipperRegionCode);
479:         $request->setShipperAddressPostalCode(Mage::getStoreConfig(self::XML_PATH_STORE_ZIP, $shipmentStoreId));
480:         $request->setShipperAddressCountryCode(Mage::getStoreConfig(self::XML_PATH_STORE_COUNTRY_ID, $shipmentStoreId));
481:         $request->setRecipientContactPersonName(trim($address->getFirstname() . ' ' . $address->getLastname()));
482:         $request->setRecipientContactPersonFirstName($address->getFirstname());
483:         $request->setRecipientContactPersonLastName($address->getLastname());
484:         $request->setRecipientContactCompanyName($address->getCompany());
485:         $request->setRecipientContactPhoneNumber($address->getTelephone());
486:         $request->setRecipientEmail($address->getEmail());
487:         $request->setRecipientAddressStreet(trim($address->getStreet1() . ' ' . $address->getStreet2()));
488:         $request->setRecipientAddressStreet1($address->getStreet1());
489:         $request->setRecipientAddressStreet2($address->getStreet2());
490:         $request->setRecipientAddressCity($address->getCity());
491:         $request->setRecipientAddressStateOrProvinceCode($address->getRegionCode());
492:         $request->setRecipientAddressRegionCode($recipientRegionCode);
493:         $request->setRecipientAddressPostalCode($address->getPostcode());
494:         $request->setRecipientAddressCountryCode($address->getCountryId());
495:         $request->setShippingMethod($shippingMethod->getMethod());
496:         $request->setPackageWeight($order->getWeight());
497:         $request->setPackages($orderShipment->getPackages());
498:         $request->setBaseCurrencyCode($baseCurrencyCode);
499:         $request->setStoreId($shipmentStoreId);
500: 
501:         return $shipmentCarrier->requestToShipment($request);
502:     }
503: }
504: 
Magento 1.7.0.2 API documentation generated by ApiGen 2.8.0