PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/magento/app/code/core/Mage/Shipping/Model/Carrier/Abstract.php

https://bitbucket.org/jit_bec/shopifine
PHP | 588 lines | 285 code | 55 blank | 248 comment | 70 complexity | b5ce1a87821453fb944fb301dd69ddcd MD5 | raw file
Possible License(s): LGPL-3.0
  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. abstract class Mage_Shipping_Model_Carrier_Abstract extends Varien_Object
  27. {
  28. /**
  29. * Carrier's code
  30. *
  31. * @var string
  32. */
  33. protected $_code;
  34. /**
  35. * Rates result
  36. *
  37. * @var array
  38. */
  39. protected $_rates = null;
  40. /**
  41. * Number of boxes in package
  42. *
  43. * @var int
  44. */
  45. protected $_numBoxes = 1;
  46. /**
  47. * Free Method config path
  48. *
  49. * @var string
  50. */
  51. protected $_freeMethod = 'free_method';
  52. /**
  53. * Whether this carrier has fixed rates calculation
  54. *
  55. * @var bool
  56. */
  57. protected $_isFixed = false;
  58. /**
  59. * Container types that could be customized
  60. *
  61. * @var array
  62. */
  63. protected $_customizableContainerTypes = array();
  64. const USA_COUNTRY_ID = 'US';
  65. const CANADA_COUNTRY_ID = 'CA';
  66. const MEXICO_COUNTRY_ID = 'MX';
  67. const HANDLING_TYPE_PERCENT = 'P';
  68. const HANDLING_TYPE_FIXED = 'F';
  69. const HANDLING_ACTION_PERPACKAGE = 'P';
  70. const HANDLING_ACTION_PERORDER = 'O';
  71. /**
  72. * Fields that should be replaced in debug with '***'
  73. *
  74. * @var array
  75. */
  76. protected $_debugReplacePrivateDataKeys = array();
  77. /**
  78. * Retrieve information from carrier configuration
  79. *
  80. * @param string $field
  81. * @return mixed
  82. */
  83. public function getConfigData($field)
  84. {
  85. if (empty($this->_code)) {
  86. return false;
  87. }
  88. $path = 'carriers/'.$this->_code.'/'.$field;
  89. return Mage::getStoreConfig($path, $this->getStore());
  90. }
  91. /**
  92. * Retrieve config flag for store by field
  93. *
  94. * @param string $field
  95. * @return bool
  96. */
  97. public function getConfigFlag($field)
  98. {
  99. if (empty($this->_code)) {
  100. return false;
  101. }
  102. $path = 'carriers/'.$this->_code.'/'.$field;
  103. return Mage::getStoreConfigFlag($path, $this->getStore());
  104. }
  105. /**
  106. * Collect and get rates
  107. *
  108. * @abstract
  109. * @param Mage_Shipping_Model_Rate_Request $request
  110. * @return Mage_Shipping_Model_Rate_Result|bool|null
  111. */
  112. abstract public function collectRates(Mage_Shipping_Model_Rate_Request $request);
  113. /**
  114. * Do request to shipment
  115. * Implementation must be in overridden method
  116. *
  117. * @param Mage_Shipping_Model_Shipment_Request $request
  118. * @return Varien_Object
  119. */
  120. public function requestToShipment(Mage_Shipping_Model_Shipment_Request $request)
  121. {
  122. return new Varien_Object();
  123. }
  124. /**
  125. * Do return of shipment
  126. * Implementation must be in overridden method
  127. *
  128. * @param $request
  129. * @return Varien_Object
  130. */
  131. public function returnOfShipment($request)
  132. {
  133. return new Varien_Object();
  134. }
  135. /**
  136. * Return container types of carrier
  137. *
  138. * @param Varien_Object|null $params
  139. * @return array
  140. */
  141. public function getContainerTypes(Varien_Object $params = null)
  142. {
  143. return array();
  144. }
  145. /**
  146. * Get allowed containers of carrier
  147. *
  148. * @param Varien_Object|null $params
  149. * @return array|bool
  150. */
  151. protected function _getAllowedContainers(Varien_Object $params = null)
  152. {
  153. $containersAll = $this->getContainerTypesAll();
  154. if (empty($containersAll)) {
  155. return array();
  156. }
  157. if (empty($params)) {
  158. return $containersAll;
  159. }
  160. $containersFilter = $this->getContainerTypesFilter();
  161. $containersFiltered = array();
  162. $method = $params->getMethod();
  163. $countryShipper = $params->getCountryShipper();
  164. $countryRecipient = $params->getCountryRecipient();
  165. if (empty($containersFilter)) {
  166. return $containersAll;
  167. }
  168. if (!$params || !$method || !$countryShipper || !$countryRecipient) {
  169. return $containersAll;
  170. }
  171. if ($countryShipper == self::USA_COUNTRY_ID && $countryRecipient == self::USA_COUNTRY_ID) {
  172. $direction = 'within_us';
  173. } else if ($countryShipper == self::USA_COUNTRY_ID && $countryRecipient != self::USA_COUNTRY_ID) {
  174. $direction = 'from_us';
  175. } else {
  176. return $containersAll;
  177. }
  178. foreach ($containersFilter as $dataItem) {
  179. $containers = $dataItem['containers'];
  180. $filters = $dataItem['filters'];
  181. if (!empty($filters[$direction]['method'])
  182. && in_array($method, $filters[$direction]['method'])
  183. ) {
  184. foreach ($containers as $container) {
  185. if (!empty($containersAll[$container])) {
  186. $containersFiltered[$container] = $containersAll[$container];
  187. }
  188. }
  189. }
  190. }
  191. return !empty($containersFiltered) ? $containersFiltered : $containersAll;
  192. }
  193. /**
  194. * Get Container Types, that could be customized
  195. *
  196. * @return array
  197. */
  198. public function getCustomizableContainerTypes()
  199. {
  200. return $this->_customizableContainerTypes;
  201. }
  202. /**
  203. * Return delivery confirmation types of carrier
  204. *
  205. * @param Varien_Object|null $params
  206. * @return array
  207. */
  208. public function getDeliveryConfirmationTypes(Varien_Object $params = null)
  209. {
  210. return array();
  211. }
  212. public function checkAvailableShipCountries(Mage_Shipping_Model_Rate_Request $request)
  213. {
  214. $speCountriesAllow = $this->getConfigData('sallowspecific');
  215. /*
  216. * for specific countries, the flag will be 1
  217. */
  218. if ($speCountriesAllow && $speCountriesAllow == 1){
  219. $showMethod = $this->getConfigData('showmethod');
  220. $availableCountries = array();
  221. if($this->getConfigData('specificcountry')) {
  222. $availableCountries = explode(',',$this->getConfigData('specificcountry'));
  223. }
  224. if ($availableCountries && in_array($request->getDestCountryId(), $availableCountries)) {
  225. return $this;
  226. } elseif ($showMethod && (!$availableCountries || ($availableCountries
  227. && !in_array($request->getDestCountryId(), $availableCountries)))
  228. ){
  229. $error = Mage::getModel('shipping/rate_result_error');
  230. $error->setCarrier($this->_code);
  231. $error->setCarrierTitle($this->getConfigData('title'));
  232. $errorMsg = $this->getConfigData('specificerrmsg');
  233. $error->setErrorMessage($errorMsg ? $errorMsg : Mage::helper('shipping')->__('The shipping module is not available for selected delivery country.'));
  234. return $error;
  235. } else {
  236. /*
  237. * The admin set not to show the shipping module if the devliery country is not within specific countries
  238. */
  239. return false;
  240. }
  241. }
  242. return $this;
  243. }
  244. /**
  245. * Processing additional validation to check is carrier applicable.
  246. *
  247. * @param Mage_Shipping_Model_Rate_Request $request
  248. * @return Mage_Shipping_Model_Carrier_Abstract|Mage_Shipping_Model_Rate_Result_Error|boolean
  249. */
  250. public function proccessAdditionalValidation(Mage_Shipping_Model_Rate_Request $request)
  251. {
  252. return $this;
  253. }
  254. /**
  255. * Determine whether current carrier enabled for activity
  256. *
  257. * @return bool
  258. */
  259. public function isActive()
  260. {
  261. $active = $this->getConfigData('active');
  262. return $active==1 || $active=='true';
  263. }
  264. /**
  265. * Whether this carrier has fixed rates calculation
  266. *
  267. * @return bool
  268. */
  269. public function isFixed()
  270. {
  271. return $this->_isFixed;
  272. }
  273. /**
  274. * Check if carrier has shipping tracking option available
  275. *
  276. * @return boolean
  277. */
  278. public function isTrackingAvailable()
  279. {
  280. return false;
  281. }
  282. /**
  283. * Check if carrier has shipping label option available
  284. *
  285. * @return boolean
  286. */
  287. public function isShippingLabelsAvailable()
  288. {
  289. return false;
  290. }
  291. /**
  292. * Retrieve sort order of current carrier
  293. *
  294. * @return mixed
  295. */
  296. public function getSortOrder()
  297. {
  298. return $this->getConfigData('sort_order');
  299. }
  300. /**
  301. * @param Mage_Shipping_Model_Rate_Request $request
  302. * @return null
  303. */
  304. protected function _updateFreeMethodQuote($request)
  305. {
  306. if ($request->getFreeMethodWeight() == $request->getPackageWeight() || !$request->hasFreeMethodWeight()) {
  307. return;
  308. }
  309. $freeMethod = $this->getConfigData($this->_freeMethod);
  310. if (!$freeMethod) {
  311. return;
  312. }
  313. $freeRateId = false;
  314. if (is_object($this->_result)) {
  315. foreach ($this->_result->getAllRates() as $i=>$item) {
  316. if ($item->getMethod() == $freeMethod) {
  317. $freeRateId = $i;
  318. break;
  319. }
  320. }
  321. }
  322. if ($freeRateId === false) {
  323. return;
  324. }
  325. $price = null;
  326. if ($request->getFreeMethodWeight() > 0) {
  327. $this->_setFreeMethodRequest($freeMethod);
  328. $result = $this->_getQuotes();
  329. if ($result && ($rates = $result->getAllRates()) && count($rates)>0) {
  330. if ((count($rates) == 1) && ($rates[0] instanceof Mage_Shipping_Model_Rate_Result_Method)) {
  331. $price = $rates[0]->getPrice();
  332. }
  333. if (count($rates) > 1) {
  334. foreach ($rates as $rate) {
  335. if ($rate instanceof Mage_Shipping_Model_Rate_Result_Method
  336. && $rate->getMethod() == $freeMethod
  337. ) {
  338. $price = $rate->getPrice();
  339. }
  340. }
  341. }
  342. }
  343. } else {
  344. /**
  345. * if we can apply free shipping for all order we should force price
  346. * to $0.00 for shipping with out sending second request to carrier
  347. */
  348. $price = 0;
  349. }
  350. /**
  351. * if we did not get our free shipping method in response we must use its old price
  352. */
  353. if (!is_null($price)) {
  354. $this->_result->getRateById($freeRateId)->setPrice($price);
  355. }
  356. }
  357. /**
  358. * Calculate price considering free shipping and handling fee
  359. *
  360. * @param string $cost
  361. * @param string $method
  362. * @return string
  363. */
  364. public function getMethodPrice($cost, $method='')
  365. {
  366. if ($method == $this->getConfigData($this->_freeMethod) && $this->getConfigData('free_shipping_enable')
  367. && $this->getConfigData('free_shipping_subtotal') <= $this->_rawRequest->getBaseSubtotalInclTax()
  368. ) {
  369. $price = '0.00';
  370. } else {
  371. $price = $this->getFinalPriceWithHandlingFee($cost);
  372. }
  373. return $price;
  374. }
  375. /**
  376. * get the handling fee for the shipping + cost
  377. *
  378. * @param float $cost
  379. * @return float final price for shipping method
  380. */
  381. public function getFinalPriceWithHandlingFee($cost)
  382. {
  383. $handlingFee = $this->getConfigData('handling_fee');
  384. $handlingType = $this->getConfigData('handling_type');
  385. if (!$handlingType) {
  386. $handlingType = self::HANDLING_TYPE_FIXED;
  387. }
  388. $handlingAction = $this->getConfigData('handling_action');
  389. if (!$handlingAction) {
  390. $handlingAction = self::HANDLING_ACTION_PERORDER;
  391. }
  392. return ($handlingAction == self::HANDLING_ACTION_PERPACKAGE)
  393. ? $this->_getPerpackagePrice($cost, $handlingType, $handlingFee)
  394. : $this->_getPerorderPrice($cost, $handlingType, $handlingFee);
  395. }
  396. /**
  397. * Get final price for shipping method with handling fee per package
  398. *
  399. * @param float $cost
  400. * @param string $handlingType
  401. * @param float $handlingFee
  402. * @return float
  403. */
  404. protected function _getPerpackagePrice($cost, $handlingType, $handlingFee)
  405. {
  406. if ($handlingType == self::HANDLING_TYPE_PERCENT) {
  407. return ($cost + ($cost * $handlingFee/100)) * $this->_numBoxes;
  408. }
  409. return ($cost + $handlingFee) * $this->_numBoxes;
  410. }
  411. /**
  412. * Get final price for shipping method with handling fee per order
  413. *
  414. * @param float $cost
  415. * @param string $handlingType
  416. * @param float $handlingFee
  417. * @return float
  418. */
  419. protected function _getPerorderPrice($cost, $handlingType, $handlingFee)
  420. {
  421. if ($handlingType == self::HANDLING_TYPE_PERCENT) {
  422. return ($cost * $this->_numBoxes) + ($cost * $this->_numBoxes * $handlingFee / 100);
  423. }
  424. return ($cost * $this->_numBoxes) + $handlingFee;
  425. }
  426. /**
  427. * Return weight in pounds
  428. *
  429. * @param integer Weight in someone measure
  430. * @return float Weight in pounds
  431. */
  432. public function convertWeightToLbs($weight)
  433. {
  434. return $weight;
  435. }
  436. /**
  437. * set the number of boxes for shipping
  438. *
  439. * @return weight
  440. */
  441. public function getTotalNumOfBoxes($weight)
  442. {
  443. /*
  444. reset num box first before retrieve again
  445. */
  446. $this->_numBoxes = 1;
  447. $weight = $this->convertWeightToLbs($weight);
  448. $maxPackageWeight = $this->getConfigData('max_package_weight');
  449. if ($weight > $maxPackageWeight && $maxPackageWeight != 0) {
  450. $this->_numBoxes = ceil($weight/$maxPackageWeight);
  451. $weight = $weight/$this->_numBoxes;
  452. }
  453. return $weight;
  454. }
  455. /**
  456. * Is state province required
  457. *
  458. * @return bool
  459. */
  460. public function isStateProvinceRequired()
  461. {
  462. return false;
  463. }
  464. /**
  465. * Check if city option required
  466. *
  467. * @return boolean
  468. */
  469. public function isCityRequired()
  470. {
  471. return false;
  472. }
  473. /**
  474. * Determine whether zip-code is required for the country of destination
  475. *
  476. * @param string|null $countryId
  477. * @return bool
  478. */
  479. public function isZipCodeRequired($countryId = null)
  480. {
  481. return false;
  482. }
  483. /**
  484. * Log debug data to file
  485. *
  486. * @param mixed $debugData
  487. */
  488. protected function _debug($debugData)
  489. {
  490. if ($this->getDebugFlag()) {
  491. Mage::getModel('core/log_adapter', 'shipping_' . $this->getCarrierCode() . '.log')
  492. ->setFilterDataKeys($this->_debugReplacePrivateDataKeys)
  493. ->log($debugData);
  494. }
  495. }
  496. /**
  497. * Define if debugging is enabled
  498. *
  499. * @return bool
  500. */
  501. public function getDebugFlag()
  502. {
  503. return $this->getConfigData('debug');
  504. }
  505. /**
  506. * Used to call debug method from not Payment Method context
  507. *
  508. * @param mixed $debugData
  509. */
  510. public function debugData($debugData)
  511. {
  512. $this->_debug($debugData);
  513. }
  514. /**
  515. * Getter for carrier code
  516. *
  517. * @return string
  518. */
  519. public function getCarrierCode()
  520. {
  521. return $this->_code;
  522. }
  523. /**
  524. * Return content types of package
  525. *
  526. * @param Varien_Object $params
  527. * @return array
  528. */
  529. public function getContentTypes(Varien_Object $params)
  530. {
  531. return array();
  532. }
  533. }