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

/src/app/plugins/kaching/controllers/components/shipping_calculator.php

http://github.com/mfriesen/kaching-php
PHP | 224 lines | 116 code | 51 blank | 57 comment | 51 complexity | bc8901fed2ff15dffe7a7be6db43f9ed MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. *
  4. * Licensed under The MIT License
  5. * Redistributions of files must retain the above copyright notice.
  6. *
  7. * @copyright Copyright KACHINGPHP.ORG 2010
  8. * @link http://www.kachingphp.org Kaching Project
  9. * @package kaching
  10. * @subpackage kaching.controllers.components
  11. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  12. */
  13. /**
  14. * Shipping Calculator component
  15. *
  16. * This class calculates shipping costs
  17. *
  18. * @author Mike Friesen
  19. *
  20. */
  21. class ShippingCalculatorComponent extends Object {
  22. function startup( &$controller ) {
  23. $this->controller = &$controller;
  24. }
  25. /**
  26. * Calculates shipping amount
  27. * @param $cart
  28. * @param $store
  29. * @param $coupon
  30. */
  31. function calculate($cart, $store, $coupon) {
  32. $shippingAmount = 0;
  33. if ($this->__hasProductIncludesShipping($cart)) {
  34. $store_id = $cart['Order']['store_id'];
  35. $shippingzone = isset($cart['Order']['shippingzone']) ? $cart['Order']['shippingzone'] : "";
  36. $country = isset($cart['Order']['shipto_country']) ? $cart['Order']['shipto_country'] : "";
  37. $region = isset($cart['Order']['shipto_region']) ? $cart['Order']['shipto_region'] : "";
  38. $postalcode = isset($cart['Order']['shipto_postalcode']) ? $cart['Order']['shipto_postalcode'] : "";
  39. $city = isset($cart['Order']['shipto_city']) ? $cart['Order']['shipto_city'] : "";
  40. $shippingzone = $this->__findShippingZone($store_id, $shippingzone, $country, $region, $postalcode, $city);
  41. $shippingweight = $this->__calculateShippingWeight($cart);
  42. if ($shippingzone != null && !empty($shippingzone)) {
  43. $shippingAmount = $this->__getShippingAmount($shippingzone, $shippingweight);
  44. }
  45. }
  46. $cart['Order']['shipping'] = $shippingAmount;
  47. $shippingCoupon = $this->__calculateShippingCoupon($cart, $coupon) * -1;
  48. $cart['Order']['shipping_coupon'] = $shippingCoupon;
  49. $shippingTax = round( ($shippingAmount + $shippingCoupon) * ($store['Store']['shipping_tax'] / 100), 2);
  50. $cart['Order']['shipping_tax'] = $shippingTax;
  51. return $cart;
  52. }
  53. /**
  54. * Calculates the shipping amount
  55. * @param $cart
  56. */
  57. function getShippingAmount($cart, $shippingzone, $country, $region, $postalcode, $city) {
  58. $shippingAmount = number_format(0, 2);
  59. if ($this->__hasProductIncludesShipping($cart)) {
  60. $store_id = $cart['Order']['store_id'];
  61. $zone = $this->__findShippingZone($store_id, $shippingzone, $country, $region, $postalcode, $city);
  62. $shippingweight = $this->__calculateShippingWeight($cart);
  63. if ($zone != null && !empty($zone)) {
  64. $shippingAmount = $this->__getShippingAmount($zone, $shippingweight);
  65. }
  66. }
  67. return $shippingAmount;
  68. }
  69. /**
  70. * Find the shipping zone for order.
  71. * Order for finding shippingzone is:
  72. * 1) Check if $shippingzone is set
  73. * 2) Check if shippingzone can be found via $country and $postalcode
  74. * NOTE: If country is canada only the first 3 letters of the postal code are used.
  75. * 3) Check if shippingzone can be found via $country and $region and $city
  76. * 4) Check if shippingzone can be found via $country and $region
  77. *
  78. */
  79. function __findShippingZone($store_id, $shippingzone=null, $country=null, $region=null, $postalcode=null, $city=null) {
  80. $zone = null;
  81. $shippingzone = $shippingzone != null && strlen($shippingzone) > 0 ? $shippingzone : null;
  82. $country = $country != null && strlen($country) > 0 ? $country : null;
  83. $region = $region != null && strlen($region) > 0 ? $region : null;
  84. $postalcode = $postalcode != null && strlen($postalcode) > 0 ? $postalcode : null;
  85. $city = $city != null && strlen($city) > 0 ? $city : null;
  86. if ($shippingzone != null && strlen($shippingzone) > 0) {
  87. $this->controller->Shippingzone->recursive=1;
  88. $zone = $this->controller->Shippingzone->findById($shippingzone);
  89. } else {
  90. $joins = array(array('table' => 'store_shippingzones', 'alias' => 'StoreShippingZone', 'type' => 'INNER', 'conditions' => array( 'StoreShippingZone.shippingzone_id = Shippingalias.shippingzone_id')));
  91. if ($country != null && $postalcode != null) {
  92. $postalcode = $country == "CA" ? substr($postalcode, 0, 3) : $postalcode;
  93. $conditions = array("country"=>$country, "postalcode"=>$postalcode, "store_id"=>$store_id);
  94. $alias = $this->controller->Shippingalias->find("first", array('conditions'=>$conditions, 'joins'=>$joins));
  95. }
  96. if (empty($alias) && $country != null && $region != null && $city != null) {
  97. $conditions = array("country"=>$country, "region"=>$region, "city"=>$city, "store_id"=>$store_id);
  98. $alias = $this->controller->Shippingalias->find("first", array('conditions'=>$conditions, 'joins'=>$joins));
  99. }
  100. if (empty($alias) && $country != null && $region != null) {
  101. $conditions = array("country"=>$country, "region"=>$region, "store_id"=>$store_id);
  102. $alias = $this->controller->Shippingalias->find("first", array('conditions'=>$conditions, 'joins'=>$joins));
  103. }
  104. if (!empty($alias)) {
  105. $this->controller->Shippingzone->recursive=1;
  106. $zone = $this->controller->Shippingzone->findById($alias['Shippingalias']['shippingzone_id']);
  107. }
  108. }
  109. return $zone;
  110. }
  111. /**
  112. * Calculates the Shipping Weight for an order
  113. * @param $cart
  114. */
  115. function __calculateShippingWeight($cart) {
  116. $shippingweight = 0;
  117. foreach ($cart['OrderDetail'] as $detail) {
  118. $shippingweight += isset($detail['Product']['weight']) ? $detail['Product']['weight'] : 0;
  119. }
  120. return $shippingweight;
  121. }
  122. /**
  123. * Calculates any coupon discount for shipping
  124. * @param $cart
  125. * @param $coupon
  126. */
  127. function __calculateShippingCoupon($cart, $coupon) {
  128. $couponAmount = 0;
  129. if ($coupon != null) {
  130. $shippingPercent = $coupon['Coupon']['shipping_percent']/100;
  131. if ($shippingPercent != 0) {
  132. $shippingAmount = $cart['Order']['shipping'];
  133. $couponAmount = round($shippingAmount * $shippingPercent, 2);
  134. }
  135. }
  136. return $couponAmount;
  137. }
  138. /**
  139. * Calculates the shipping amount not including any coupons
  140. * @param $zone
  141. * @param $shippingweight
  142. */
  143. function __getShippingAmount($zone, $shippingweight) {
  144. $retAmount = 0;
  145. foreach($zone['Shippingamount'] as $shippingAmount):
  146. $weight = $shippingAmount['weight'];
  147. $amount = $shippingAmount['amount'];
  148. if ($weight == $shippingweight) {
  149. return number_format($amount, 2);
  150. }
  151. if ($retAmount == 0) {
  152. $retAmount = $amount;
  153. }
  154. if ($shippingweight > $weight) {
  155. $retAmount = $amount;
  156. }
  157. endforeach;
  158. return number_format($retAmount, 2);
  159. }
  160. /**
  161. * Checks products to see if we charge shipping
  162. * @param $cart
  163. */
  164. function __hasProductIncludesShipping($cart) {
  165. foreach ($cart['OrderDetail'] as $detail) {
  166. if ($detail['ProductStore']['shipping'] == 1) {
  167. return true;
  168. }
  169. }
  170. return false;
  171. }
  172. }
  173. ?>