uc_weightquote.module 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /**
  3. * @file
  4. * Shipping quote module that defines a weight-based shipping rate for each
  5. * product.
  6. */
  7. /**
  8. * Implements hook_menu().
  9. */
  10. function uc_weightquote_menu() {
  11. $items = array();
  12. $items['admin/store/settings/quotes/methods/weightquote/add'] = array(
  13. 'title' => 'Add weight quote',
  14. 'description' => 'Create a new weight based shipping quote.',
  15. 'page callback' => 'drupal_get_form',
  16. 'page arguments' => array('uc_weightquote_admin_method_edit_form'),
  17. 'access arguments' => array('configure quotes'),
  18. 'type' => MENU_LOCAL_ACTION,
  19. 'file' => 'uc_weightquote.admin.inc',
  20. );
  21. $items['admin/store/settings/quotes/methods/weightquote/%'] = array(
  22. 'title' => 'Edit weight quote method',
  23. 'description' => 'Edit an existing weight based shipping quote.',
  24. 'page callback' => 'drupal_get_form',
  25. 'page arguments' => array('uc_weightquote_admin_method_edit_form', 6),
  26. 'access arguments' => array('configure quotes'),
  27. 'file' => 'uc_weightquote.admin.inc',
  28. );
  29. $items['admin/store/settings/quotes/weightquote/%/delete'] = array(
  30. 'title' => 'Delete weight quote method',
  31. 'description' => 'Delete a weight based shipping quote.',
  32. 'page callback' => 'drupal_get_form',
  33. 'page arguments' => array('uc_weightquote_admin_method_confirm_delete', 5),
  34. 'access arguments' => array('configure quotes'),
  35. 'file' => 'uc_weightquote.admin.inc',
  36. );
  37. return $items;
  38. }
  39. /**
  40. * Implements hook_form_alter().
  41. *
  42. * Adds a form element for the shipping rate of a product.
  43. */
  44. function uc_weightquote_form_alter(&$form, &$form_state, $form_id) {
  45. if (uc_product_is_product_form($form)) {
  46. $weight = variable_get('uc_quote_method_weight', array());
  47. $result = db_query("SELECT mid, title, product_rate FROM {uc_weightquote_methods}");
  48. foreach ($result as $method) {
  49. // Ensure the default weight is set.
  50. $weight += array('weightquote_' . $method->mid => 0);
  51. if (!isset($form['shipping']['weightquote'])) {
  52. $form['shipping']['weightquote'] = array(
  53. '#type' => 'fieldset',
  54. '#title' => t('Shipping rates by weight'),
  55. '#description' => t("Overrides the default shipping rate per product for each flat rate shipping method. Leave field empty to use the method's default value."),
  56. '#tree' => TRUE,
  57. '#collapsible' => TRUE,
  58. '#collapsed' => FALSE,
  59. '#weight' => 0,
  60. );
  61. }
  62. $form['shipping']['weightquote'][$method->mid] = array(
  63. '#type' => 'uc_price',
  64. '#title' => check_plain($method->title),
  65. '#default_value' => isset($form['#node']->weightquote[$method->mid]) ? $form['#node']->weightquote[$method->mid] : '',
  66. '#description' => t('Default rate: %price per @unit', array('%price' => uc_currency_format($method->product_rate), '@unit' => variable_get('uc_weight_unit', 'lb'))),
  67. '#field_suffix' => t('per @unit', array('@unit' => variable_get('uc_weight_unit', 'lb'))),
  68. '#weight' => $weight['weightquote_' . $method->mid],
  69. '#empty_zero' => FALSE,
  70. );
  71. }
  72. }
  73. }
  74. /**
  75. * Implements hook_node_insert().
  76. */
  77. function uc_weightquote_node_insert($node) {
  78. uc_weightquote_node_update($node);
  79. }
  80. /**
  81. * Implements hook_node_update().
  82. */
  83. function uc_weightquote_node_update($node) {
  84. if (uc_product_is_product($node->type)) {
  85. if (isset($node->weightquote) && is_array($node->weightquote)) {
  86. if (empty($node->revision)) {
  87. db_delete('uc_weightquote_products')
  88. ->condition('vid', $node->vid)
  89. ->execute();
  90. }
  91. $query = db_insert('uc_weightquote_products')
  92. ->fields(array('vid', 'nid', 'mid', 'rate'));
  93. foreach ($node->weightquote as $mid => $rate) {
  94. if (is_numeric($rate) && $rate >= 0) {
  95. $query->values(array(
  96. 'vid' => $node->vid,
  97. 'nid' => $node->nid,
  98. 'mid' => $mid,
  99. 'rate' => $rate,
  100. ));
  101. }
  102. }
  103. $query->execute();
  104. }
  105. }
  106. }
  107. /**
  108. * Implements hook_node_load().
  109. */
  110. function uc_weightquote_node_load($nodes, $types) {
  111. $vids = array();
  112. $product_types = uc_product_types();
  113. foreach ($nodes as &$node) {
  114. if (in_array($node->type, $product_types)) {
  115. $vids[$node->nid] = $node->vid;
  116. }
  117. }
  118. if ($vids) {
  119. $result = db_query("SELECT nid, mid, rate FROM {uc_weightquote_products} WHERE vid IN (:vids)", array(':vids' => $vids));
  120. foreach ($result as $method) {
  121. $nodes[$method->nid]->weightquote[$method->mid] = $method->rate;
  122. }
  123. }
  124. }
  125. /**
  126. * Implements hook_node_delete().
  127. */
  128. function uc_weightquote_node_delete($node) {
  129. db_delete('uc_weightquote_products')
  130. ->condition('nid', $node->nid)
  131. ->execute();
  132. }
  133. /**
  134. * Implements hook_node_revision_delete().
  135. */
  136. function uc_weightquote_node_revision_delete($node) {
  137. db_delete('uc_weightquote_products')
  138. ->condition('vid', $node->vid)
  139. ->execute();
  140. }
  141. /**
  142. * Implements hook_uc_shipping_method().
  143. */
  144. function uc_weightquote_uc_shipping_method() {
  145. $methods = array();
  146. $result = db_query("SELECT mid, title, label, base_rate, product_rate FROM {uc_weightquote_methods}");
  147. foreach ($result as $method) {
  148. $methods['weightquote_' . $method->mid] = array(
  149. 'id' => 'weightquote_' . $method->mid,
  150. 'module' => 'uc_weightquote',
  151. 'title' => $method->title,
  152. 'description' => t('!base_rate + !product_rate per !unit', array('!base_rate' => uc_currency_format($method->base_rate), '!product_rate' => uc_currency_format($method->product_rate), '!unit' => variable_get('uc_weight_unit', 'lb'))),
  153. 'operations' => array(
  154. 'edit' => array(
  155. 'title' => t('edit'),
  156. 'href' => 'admin/store/settings/quotes/methods/weightquote/' . $method->mid,
  157. ),
  158. 'delete' => array(
  159. 'title' => t('delete'),
  160. 'href' => 'admin/store/settings/quotes/weightquote/' . $method->mid . '/delete',
  161. ),
  162. ),
  163. 'quote' => array(
  164. 'type' => 'order',
  165. 'callback' => 'uc_weightquote_quote',
  166. 'accessorials' => array(
  167. $method->label,
  168. ),
  169. ),
  170. 'enabled' => TRUE,
  171. );
  172. }
  173. return $methods;
  174. }
  175. /**
  176. * Standard callback to return a shipping rate via the weight quote method.
  177. *
  178. * @param $products
  179. * The order's products.
  180. * @param $details
  181. * Other order details including a shipping address.
  182. * @param $method
  183. * The shipping method to use to create the quote.
  184. *
  185. * @return
  186. * An array containing the shipping quote for the order.
  187. */
  188. function uc_weightquote_quote($products, $details, $method) {
  189. $method = explode('_', $method['id']);
  190. $mid = $method[1];
  191. if ($method = db_query("SELECT * FROM {uc_weightquote_methods} WHERE mid = :mid", array(':mid' => $mid))->fetchObject()) {
  192. // Start at the base rate.
  193. $rate = $method->base_rate;
  194. foreach ($products as $product) {
  195. if (!isset($product->weightquote[$mid])) {
  196. // Add the method's default product rate.
  197. $product_rate = $method->product_rate * $product->qty;
  198. }
  199. else {
  200. // Add the product-specific rate.
  201. $product_rate = $product->weightquote[$mid] * $product->qty;
  202. }
  203. $rate += $product_rate * $product->weight * uc_weight_conversion($product->weight_units, variable_get('uc_weight_unit', 'lb'));
  204. }
  205. $quotes[] = array(
  206. 'rate' => $rate,
  207. 'label' => check_plain($method->label),
  208. 'option_label' => check_plain($method->label),
  209. );
  210. }
  211. return $quotes;
  212. }