uc_taxes.admin.inc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <?php
  2. /**
  3. * @file
  4. * Taxes administration menu items.
  5. */
  6. /**
  7. * Displays a list of tax rates.
  8. */
  9. function uc_taxes_admin_settings() {
  10. $header = array(t('Name'), t('Rate'), t('Taxed products'), t('Taxed product types'), t('Taxed line items'), t('Weight'), array('data' => t('Operations'), 'colspan' => 4));
  11. $rows = array();
  12. $options = array('query' => array('token' => drupal_get_token('uc_taxes_clone')));
  13. foreach (uc_taxes_rate_load() as $rate_id => $rate) {
  14. $rows[] = array(
  15. check_plain($rate->name),
  16. $rate->rate * 100 . '%',
  17. $rate->shippable ? t('Shippable products') : t('Any product'),
  18. implode(', ', $rate->taxed_product_types),
  19. implode(', ', $rate->taxed_line_items),
  20. $rate->weight,
  21. l(t('edit'), 'admin/store/settings/taxes/' . $rate_id . '/edit'),
  22. l(t('conditions'), 'admin/store/settings/taxes/manage/uc_taxes_' . $rate_id),
  23. l(t('clone'), 'admin/store/settings/taxes/' . $rate_id . '/clone', $options),
  24. l(t('delete'), 'admin/store/settings/taxes/' . $rate_id . '/delete'),
  25. );
  26. }
  27. $build['taxes'] = array(
  28. '#theme' => 'table',
  29. '#header' => $header,
  30. '#rows' => $rows,
  31. '#empty' => t('No rates available.'),
  32. );
  33. return $build;
  34. }
  35. /**
  36. * Builds a form to add or edit a tax rate.
  37. *
  38. * @param $rate_id
  39. * The ID of the tax rate to edit; leave NULL to add a new rate.
  40. *
  41. * @see uc_taxes_form_validate()
  42. * @see uc_taxes_form_submit()
  43. * @ingroup forms
  44. */
  45. function uc_taxes_form($form, &$form_state, $rate_id = NULL) {
  46. // If a rate ID was specified...
  47. if ($rate_id) {
  48. // Load the tax rate and set the page title.
  49. $rate = uc_taxes_rate_load($rate_id);
  50. drupal_set_title($rate->name);
  51. }
  52. $form['id'] = array(
  53. '#type' => 'value',
  54. '#value' => $rate_id,
  55. );
  56. $form['name'] = array(
  57. '#type' => 'textfield',
  58. '#title' => t('Name'),
  59. '#description' => t('This name will appear to the customer when this tax is applied to an order.'),
  60. '#default_value' => $rate_id ? $rate->name : '',
  61. '#required' => TRUE,
  62. );
  63. $form['rate'] = array(
  64. '#type' => 'textfield',
  65. '#title' => t('Rate'),
  66. '#description' => t('The tax rate as a percent or decimal. Examples: 6%, .06'),
  67. '#default_value' => $rate_id ? (($rate->rate * 100) . '%') : '',
  68. '#size' => 15,
  69. '#required' => TRUE,
  70. );
  71. $form['shippable'] = array(
  72. '#type' => 'radios',
  73. '#title' => t('Taxed products'),
  74. '#options' => array(
  75. t('Apply tax to any product regardless of its shippability.'),
  76. t('Apply tax to shippable products only.'),
  77. ),
  78. '#default_value' => $rate_id ? $rate->shippable : 0,
  79. );
  80. // TODO: Remove the need for a special case for product kit module.
  81. $options = uc_product_type_names();
  82. unset($options['product_kit']);
  83. $options['blank-line'] = t('"Blank line" product');
  84. $form['taxed_product_types'] = array(
  85. '#type' => 'checkboxes',
  86. '#title' => t('Taxed product types'),
  87. '#description' => t('Apply taxes to the specified product types/classes.'),
  88. '#options' => $options,
  89. '#default_value' => $rate_id ? $rate->taxed_product_types : array(),
  90. );
  91. $options = array();
  92. foreach (_uc_line_item_list() as $id => $line_item) {
  93. if (!in_array($id, array('subtotal', 'tax_subtotal', 'total', 'tax_display'))) {
  94. $options[$id] = $line_item['title'];
  95. }
  96. }
  97. $form['taxed_line_items'] = array(
  98. '#type' => 'checkboxes',
  99. '#title' => t('Taxed line items'),
  100. '#description' => t('Adds the checked line item types to the total before applying this tax.'),
  101. '#options' => $options,
  102. '#default_value' => $rate_id ? $rate->taxed_line_items : array(),
  103. );
  104. $form['weight'] = array(
  105. '#type' => 'weight',
  106. '#title' => t('Weight'),
  107. '#description' => t('Taxes are sorted by weight and then applied to the order sequentially. This value is important when taxes need to include other tax line items.'),
  108. '#default_value' => $rate_id ? $rate->weight : 0,
  109. );
  110. $form['display_include'] = array(
  111. '#type' => 'checkbox',
  112. '#title' => t('Include this tax when displaying product prices.'),
  113. '#default_value' => $rate_id ? $rate->display_include : 0,
  114. );
  115. $form['inclusion_text'] = array(
  116. '#type' => 'textfield',
  117. '#title' => t('Tax inclusion text'),
  118. '#description' => t('This text will be displayed near the price to indicate that it includes tax.'),
  119. '#default_value' => $rate_id ? $rate->inclusion_text : '',
  120. );
  121. $form['actions'] = array('#type' => 'actions');
  122. $form['actions']['submit'] = array(
  123. '#type' => 'submit',
  124. '#value' => t('Submit'),
  125. '#suffix' => l(t('Cancel'), 'admin/store/settings/taxes'),
  126. );
  127. return $form;
  128. }
  129. /**
  130. * Ensures that tax rates are positive numbers.
  131. *
  132. * @see uc_taxes_form()
  133. * @see uc_taxes_form_submit()
  134. */
  135. function uc_taxes_form_validate($form, &$form_state) {
  136. if (!empty($form_state['values']['rate']) && (floatval($form_state['values']['rate']) < 0)) {
  137. form_set_error('rate', t('Rate must be a positive number. No commas and only one decimal point.'));
  138. }
  139. }
  140. /**
  141. * Form submission handler for uc_taxes_form().
  142. *
  143. * @see uc_taxes_form()
  144. * @see uc_taxes_form_validate()
  145. */
  146. function uc_taxes_form_submit($form, &$form_state) {
  147. // Determine the decimal rate value.
  148. if (strpos($form_state['values']['rate'], '%')) {
  149. $form_state['values']['rate'] = floatval($form_state['values']['rate']) / 100;
  150. }
  151. else {
  152. $form_state['values']['rate'] = floatval($form_state['values']['rate']);
  153. }
  154. // Build the rate object based on the form values and save it.
  155. $rate = (object) array(
  156. 'id' => $form_state['values']['id'],
  157. 'name' => $form_state['values']['name'],
  158. 'rate' => $form_state['values']['rate'],
  159. 'taxed_product_types' => array_filter($form_state['values']['taxed_product_types']),
  160. 'taxed_line_items' => array_filter($form_state['values']['taxed_line_items']),
  161. 'weight' => $form_state['values']['weight'],
  162. 'shippable' => $form_state['values']['shippable'],
  163. 'display_include' => $form_state['values']['display_include'],
  164. 'inclusion_text' => $form_state['values']['inclusion_text'],
  165. );
  166. $rate = uc_taxes_rate_save($rate);
  167. // Update the name of the associated conditions.
  168. $conditions = rules_config_load('uc_taxes_' . $form_state['values']['id']);
  169. if ($conditions) {
  170. $conditions->label = $form_state['values']['name'];
  171. $conditions->save();
  172. }
  173. // Display a message and redirect back to the overview,
  174. // or the conditions page for new taxes.
  175. if ($form_state['values']['id']) {
  176. drupal_set_message(t('Tax rate %name saved.', array('%name' => $form_state['values']['name'])));
  177. $form_state['redirect'] = 'admin/store/settings/taxes';
  178. }
  179. else {
  180. drupal_set_message(t('Tax rate %name created.', array('%name' => $form_state['values']['name'])));
  181. $form_state['redirect'] = 'admin/store/settings/taxes/manage/uc_taxes_' . $rate->id;
  182. }
  183. }
  184. /**
  185. * Clones a tax rate.
  186. */
  187. function uc_taxes_clone($rate_id) {
  188. if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'uc_taxes_clone')) {
  189. return MENU_ACCESS_DENIED;
  190. }
  191. // Load the source rate object.
  192. $rate = uc_taxes_rate_load($rate_id);
  193. $name = $rate->name;
  194. // Tweak the name and unset the rate ID.
  195. $rate->name = t('Copy of !name', array('!name' => $rate->name));
  196. $rate->id = NULL;
  197. // Save the new rate without clearing the Rules cache.
  198. $rate = uc_taxes_rate_save($rate, FALSE);
  199. // Clone the associated conditions as well.
  200. if ($conditions = rules_config_load('uc_taxes_' . $rate_id)) {
  201. $conditions->id = NULL;
  202. $conditions->name = '';
  203. $conditions->save('uc_taxes_' . $rate->id);
  204. }
  205. entity_flush_caches();
  206. // Display a message and redirect back to the overview.
  207. drupal_set_message(t('Tax rate %name cloned.', array('%name' => $name)));
  208. drupal_goto('admin/store/settings/taxes');
  209. }
  210. /**
  211. * Deletes a tax rule.
  212. *
  213. * @see uc_taxes_delete_form_submit()
  214. * @ingroup forms
  215. */
  216. function uc_taxes_delete_form($form, &$form_state, $rate_id) {
  217. // Bail if we got a bad rate ID.
  218. if (!$rate = uc_taxes_rate_load($rate_id)) {
  219. drupal_set_message(t('That tax rate does not exist.'), 'error');
  220. drupal_goto('admin/store/settings/taxes');
  221. }
  222. $form['rate_id'] = array(
  223. '#type' => 'value',
  224. '#value' => $rate_id,
  225. );
  226. $form['name'] = array(
  227. '#type' => 'value',
  228. '#value' => $rate->name,
  229. );
  230. return confirm_form($form, t('Are you sure you want to delete @name?', array('@name' => $rate->name)), 'admin/store/settings/taxes', t('This action cannot be undone. Any orders that have been charged this tax may lose tax if you proceed.<br />If you just want this tax to no longer be applied to orders, consider disabling its predicate instead.'), t('Delete'), t('Cancel'));
  231. }
  232. /**
  233. * Form submission handler for uc_taxes_delete_form().
  234. *
  235. * @see uc_taxes_delete_form()
  236. */
  237. function uc_taxes_delete_form_submit($form, &$form_state) {
  238. // Delete the tax rate.
  239. uc_taxes_rate_delete($form_state['values']['rate_id']);
  240. // Display a message and redirect back to the overview.
  241. drupal_set_message(t('Tax rate %name deleted.', array('%name' => $form_state['values']['name'])));
  242. $form_state['redirect'] = 'admin/store/settings/taxes';
  243. }