uc_taxes.module 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. <?php
  2. /**
  3. * @file
  4. * Ubercart Taxes module.
  5. *
  6. * Allows tax rules to be set up and applied to orders.
  7. */
  8. /**
  9. * Implements hook_permission().
  10. */
  11. function uc_taxes_permission() {
  12. return array(
  13. 'configure taxes' => array(
  14. 'title' => t('Configure taxes'),
  15. ),
  16. );
  17. }
  18. /**
  19. * Implements hook_menu().
  20. */
  21. function uc_taxes_menu() {
  22. $items = array();
  23. $items['admin/store/settings/taxes'] = array(
  24. 'title' => 'Taxes',
  25. 'description' => 'Configure tax rates and rules.',
  26. 'page callback' => 'uc_taxes_admin_settings',
  27. 'access arguments' => array('configure taxes'),
  28. 'file' => 'uc_taxes.admin.inc',
  29. );
  30. $items['admin/store/settings/taxes/add'] = array(
  31. 'title' => 'Add a tax rate',
  32. 'page callback' => 'drupal_get_form',
  33. 'page arguments' => array('uc_taxes_form'),
  34. 'access arguments' => array('configure taxes'),
  35. 'file' => 'uc_taxes.admin.inc',
  36. 'type' => MENU_LOCAL_ACTION,
  37. );
  38. $items['admin/store/settings/taxes/%/edit'] = array(
  39. 'title' => 'Edit a tax rate',
  40. 'page callback' => 'drupal_get_form',
  41. 'page arguments' => array('uc_taxes_form', 4),
  42. 'access arguments' => array('configure taxes'),
  43. 'file' => 'uc_taxes.admin.inc',
  44. );
  45. $items['admin/store/settings/taxes/%/clone'] = array(
  46. 'page callback' => 'uc_taxes_clone',
  47. 'page arguments' => array(4),
  48. 'access arguments' => array('configure taxes'),
  49. 'file' => 'uc_taxes.admin.inc',
  50. );
  51. $items['admin/store/settings/taxes/%/delete'] = array(
  52. 'title' => 'Delete tax rule',
  53. 'page callback' => 'drupal_get_form',
  54. 'page arguments' => array('uc_taxes_delete_form', 4),
  55. 'access arguments' => array('configure taxes'),
  56. 'file' => 'uc_taxes.admin.inc',
  57. );
  58. $items += rules_ui()->config_menu('admin/store/settings/taxes');
  59. return $items;
  60. }
  61. /**
  62. * Implements hook_module_implements_alter().
  63. *
  64. * Ensures that all other line items are added to the order before tax
  65. * calculations are made.
  66. */
  67. function uc_taxes_module_implements_alter(&$implementations, $hook) {
  68. if (in_array($hook, array('uc_order', 'entity_view_alter'))) {
  69. $group = $implementations['uc_taxes'];
  70. unset($implementations['uc_taxes']);
  71. $implementations['uc_taxes'] = $group;
  72. }
  73. }
  74. /**
  75. * Implements hook_form_uc_order_edit_form_alter().
  76. */
  77. function uc_taxes_form_uc_order_edit_form_alter(&$form, &$form_state) {
  78. $order = $form['#order'];
  79. $line_items = $order->line_items;
  80. foreach ($line_items as $item) {
  81. // Tax line items are stored in the database, but they can't be changed by
  82. // the user.
  83. if ($item['type'] == 'tax') {
  84. $form['line_items'][$item['line_item_id']]['title'] = array(
  85. '#markup' => check_plain($item['title']),
  86. );
  87. $form['line_items'][$item['line_item_id']]['amount'] = array(
  88. '#theme' => 'uc_price',
  89. '#price' => $item['amount'],
  90. );
  91. }
  92. }
  93. }
  94. /**
  95. * Implements hook_entity_view_alter().
  96. *
  97. * Adds included taxes (VAT) to display price of applicable products.
  98. */
  99. function uc_taxes_entity_view_alter(&$build, $entity_type) {
  100. switch ($entity_type) {
  101. case 'node':
  102. if (uc_product_is_product($build['#node'])) {
  103. list($amount, $suffixes) = uc_taxes_get_included_tax($build['#node']);
  104. $build['display_price']['#value'] += $amount;
  105. if (!empty($suffixes)) {
  106. $build['display_price']['#suffixes'] += $suffixes;
  107. }
  108. }
  109. break;
  110. case 'uc_cart_item':
  111. list($amount, $suffixes) = uc_taxes_get_included_tax($build['#entity'], isset($build['#entity']->order) ? $build['#entity']->order : NULL);
  112. if (!empty($amount) && !empty($build['#total'])) {
  113. $build['#total'] += $amount * $build['qty']['#default_value'];
  114. }
  115. if (!empty($suffixes)) {
  116. if (empty($build['#suffixes'])) {
  117. $build['#suffixes'] = array();
  118. }
  119. $build['#suffixes'] += $suffixes;
  120. }
  121. break;
  122. case 'uc_order_product':
  123. list($amount, $suffixes) = uc_taxes_get_included_tax($build['#entity'], isset($build['#entity']->order) ? $build['#entity']->order : NULL);
  124. $build['price']['#price'] += $amount;
  125. $build['total']['#price'] += $amount * $build['#entity']->qty;
  126. $build['price']['#suffixes'] += $suffixes;
  127. $build['total']['#suffixes'] += $suffixes;
  128. break;
  129. }
  130. }
  131. /**
  132. * Implements hook_uc_line_item().
  133. */
  134. function uc_taxes_uc_line_item() {
  135. $items['tax'] = array(
  136. 'title' => t('Tax'),
  137. 'weight' => 9,
  138. 'stored' => TRUE,
  139. 'default' => FALSE,
  140. 'calculated' => TRUE,
  141. 'display_only' => FALSE,
  142. );
  143. $items['tax_display'] = array(
  144. 'title' => t('Tax'),
  145. 'callback' => 'uc_line_item_tax_display',
  146. 'weight' => 5,
  147. 'stored' => FALSE,
  148. 'calculated' => TRUE,
  149. 'display_only' => TRUE,
  150. );
  151. $items['tax_subtotal'] = array(
  152. 'title' => t('Subtotal excluding taxes'),
  153. 'callback' => 'uc_line_item_tax_subtotal',
  154. 'weight' => 7,
  155. 'stored' => FALSE,
  156. 'calculated' => FALSE,
  157. 'display_only' => TRUE,
  158. );
  159. return $items;
  160. }
  161. /**
  162. * Implements hook_uc_order().
  163. *
  164. * Updates and saves tax line items to the order.
  165. */
  166. function uc_taxes_uc_order($op, $order, $arg2) {
  167. switch ($op) {
  168. case 'save':
  169. $changes = array();
  170. $line_items = uc_taxes_calculate($order);
  171. foreach ($line_items as $id => $tax) {
  172. $line_items[$id] = _uc_taxes_to_line_item($tax);
  173. }
  174. // Loop through existing line items and update or delete as necessary.
  175. if (is_array($order->line_items)) {
  176. foreach ($order->line_items as $i => $line) {
  177. if ($line['type'] == 'tax') {
  178. $delete = TRUE;
  179. foreach ($line_items as $id => $new_line) {
  180. if ($new_line['data']['tax_id'] == $line['data']['tax_id']) {
  181. if ($new_line['amount'] != $line['amount']) {
  182. uc_order_update_line_item($line['line_item_id'], $new_line['title'], $new_line['amount'], $new_line['data']);
  183. $order->line_items[$i]['amount'] = $new_line['amount'];
  184. $order->line_items[$i]['data'] = $new_line['data'];
  185. $changes[] = t('Changed %title to %amount.', array('%amount' => uc_currency_format($new_line['amount']), '%title' => $new_line['title']));
  186. }
  187. unset($line_items[$id]);
  188. $delete = FALSE;
  189. break;
  190. }
  191. }
  192. if ($delete) {
  193. uc_order_delete_line_item($line['line_item_id']);
  194. unset($order->line_items[$i]);
  195. $changes[] = t('Removed %title.', array('%title' => $line['title']));
  196. }
  197. }
  198. }
  199. }
  200. // Now add line items for any remaining new taxes.
  201. if (is_array($line_items)) {
  202. foreach ($line_items as $line) {
  203. $order->line_items[] = uc_order_line_item_add($order->order_id, 'tax', $line['title'], $line['amount'], $line['weight'], $line['data']);
  204. $changes[] = t('Added %amount for %title.', array('%amount' => uc_currency_format($line['amount']), '%title' => $line['title']));
  205. }
  206. }
  207. // And log the changes to the order.
  208. if (count($changes)) {
  209. uc_order_log_changes($order->order_id, $changes);
  210. usort($order->line_items, 'uc_weight_sort');
  211. }
  212. break;
  213. }
  214. }
  215. /**
  216. * Implements hook_node_type_update().
  217. *
  218. * Ensure taxed product type are synchronised if the content type is updated.
  219. */
  220. function uc_taxes_node_type_update($info) {
  221. $existing_type = !empty($info->old_type) ? $info->old_type : $info->type;
  222. db_update('uc_taxed_product_types')
  223. ->fields(array(
  224. 'type' => $info->type,
  225. ))
  226. ->condition('type', $existing_type)
  227. ->execute();
  228. }
  229. /**
  230. * Tax line item callback.
  231. */
  232. function uc_line_item_tax_display($op, $order) {
  233. switch ($op) {
  234. case 'display':
  235. $lines = array();
  236. $taxes = uc_taxes_calculate($order);
  237. foreach ($taxes as $tax) {
  238. foreach ($order->line_items as $line_item) {
  239. if ($line_item['type'] == 'tax' && $line_item['data']['tax_id'] == $tax->id) {
  240. continue 2;
  241. }
  242. }
  243. $lines[] = _uc_taxes_to_line_item($tax);
  244. }
  245. return $lines;
  246. }
  247. }
  248. /**
  249. * Converts a tax object to the format expected by line item callbacks.
  250. *
  251. * @param $tax
  252. * A tax object as returned by hook_uc_taxes_calculate().
  253. *
  254. * @return array
  255. * A line item array suitable for returning from line item callbacks.
  256. */
  257. function _uc_taxes_to_line_item($tax) {
  258. $line = array(
  259. 'id' => ($tax->summed ? 'tax' : 'tax_included'),
  260. 'title' => !empty($tax->name) ? $tax->name : $tax->id,
  261. 'amount' => $tax->amount,
  262. 'weight' => variable_get('uc_li_tax_weight', 9) + (!empty($tax->weight) ? $tax->weight / 10 : 0),
  263. 'data' => isset($tax->data) ? $tax->data : array(),
  264. );
  265. $line['data']['tax_id'] = $tax->id;
  266. return $line;
  267. }
  268. /**
  269. * Handles the line item subtotal before taxes.
  270. */
  271. function uc_line_item_tax_subtotal($op, $order) {
  272. $amount = 0;
  273. switch ($op) {
  274. case 'display':
  275. $has_taxes = FALSE;
  276. $different = FALSE;
  277. if (is_array($order->products)) {
  278. foreach ($order->products as $item) {
  279. $amount += $item->price * $item->qty;
  280. }
  281. }
  282. if (is_array($order->line_items)) {
  283. foreach ($order->line_items as $key => $line_item) {
  284. if ($line_item['type'] == 'subtotal') {
  285. continue;
  286. }
  287. if (substr($line_item['type'], 0, 3) != 'tax') {
  288. $amount += $line_item['amount'];
  289. $different = TRUE;
  290. }
  291. else {
  292. $has_taxes = TRUE;
  293. }
  294. }
  295. }
  296. if (isset($order->taxes) && is_array($order->taxes) && count($order->taxes)) {
  297. $has_taxes = TRUE;
  298. }
  299. if ($different && $has_taxes) {
  300. return array(array(
  301. 'id' => 'tax_subtotal',
  302. 'title' => t('Subtotal excluding taxes'),
  303. 'amount' => $amount,
  304. 'weight' => variable_get('uc_li_tax_subtotal_weight', 7),
  305. ));
  306. }
  307. break;
  308. }
  309. }
  310. /**
  311. * Saves a tax rate to the database.
  312. *
  313. * @param $rate
  314. * The tax rate object to be saved.
  315. * @param bool $reset
  316. * If TRUE, resets the Rules cache after saving. Defaults to TRUE.
  317. *
  318. * @return
  319. * The saved tax rate object including the rate ID for new rates.
  320. */
  321. function uc_taxes_rate_save($rate, $reset = TRUE) {
  322. // Save it as a new rate if no ID is specified.
  323. if (empty($rate->id)) {
  324. drupal_write_record('uc_taxes', $rate);
  325. }
  326. // Otherwise update the existing tax rate's data.
  327. else {
  328. drupal_write_record('uc_taxes', $rate, array('id'));
  329. }
  330. db_delete('uc_taxed_product_types')
  331. ->condition('tax_id', $rate->id)
  332. ->execute();
  333. db_delete('uc_taxed_line_items')
  334. ->condition('tax_id', $rate->id)
  335. ->execute();
  336. $p_insert = db_insert('uc_taxed_product_types')->fields(array('tax_id', 'type'));
  337. $l_insert = db_insert('uc_taxed_line_items')->fields(array('tax_id', 'type'));
  338. foreach ($rate->taxed_product_types as $type) {
  339. $p_insert->values(array(
  340. 'tax_id' => $rate->id,
  341. 'type' => $type,
  342. ));
  343. }
  344. foreach ($rate->taxed_line_items as $type) {
  345. $l_insert->values(array(
  346. 'tax_id' => $rate->id,
  347. 'type' => $type,
  348. ));
  349. }
  350. $p_insert->execute();
  351. $l_insert->execute();
  352. if ($reset) {
  353. // Ensure Rules picks up the new condition.
  354. entity_flush_caches();
  355. }
  356. return $rate;
  357. }
  358. /**
  359. * List all the taxes that can apply to an order.
  360. *
  361. * The taxes depend on the order status. For orders which are still in
  362. * checkout, any tax can apply. For orders out of checkout, only taxes
  363. * originally saved as line items can apply.
  364. *
  365. * @param $order
  366. * The order that taxes are being calculated for.
  367. */
  368. function uc_taxes_filter_rates($order) {
  369. $taxes = array();
  370. // If no order, then just return all rates.
  371. if (empty($order)) {
  372. $taxes = uc_taxes_rate_load();
  373. }
  374. // For orders no longer in checkout, only the saved tax rates can apply.
  375. elseif (isset($order->order_status) && uc_order_status_data($order->order_status, 'state') != 'in_checkout') {
  376. if (isset($order->line_items)) {
  377. foreach ($order->line_items as $item) {
  378. if ($item['type'] == 'tax') {
  379. if (!empty($item['data']['tax'])) {
  380. // Use the rate stored in the line-item.
  381. $taxes[] = clone $item['data']['tax'];
  382. }
  383. elseif (!empty($item['data']['tax_id']) && $tax = uc_taxes_rate_load($item['data']['tax_id'])) {
  384. // For old orders that don't have all the tax info, all we can do
  385. // is preserve the rate.
  386. $tax = clone $tax;
  387. if (!empty($item['data']['tax_rate'])) {
  388. $tax->rate = $item['data']['tax_rate'];
  389. }
  390. $taxes[] = $tax;
  391. }
  392. }
  393. }
  394. }
  395. }
  396. // For orders still in checkout, any tax whose conditions are satisfied can
  397. // apply.
  398. else {
  399. foreach (uc_taxes_rate_load() as $rate) {
  400. $tax = clone $rate;
  401. if (rules_invoke_component('uc_taxes_' . $tax->id, $order)) {
  402. $taxes[] = $tax;
  403. }
  404. }
  405. }
  406. return $taxes;
  407. }
  408. /**
  409. * Loads a tax rate or all tax rates from the database.
  410. *
  411. * @param $rate_id
  412. * The ID of the specific rate to load or NULL to return all available rates.
  413. *
  414. * @return
  415. * An object representing the requested tax rate or an array of all tax rates
  416. * keyed by rate ID.
  417. */
  418. function uc_taxes_rate_load($rate_id = NULL) {
  419. static $rates = array();
  420. // If the rates have not been cached yet...
  421. if (empty($rates)) {
  422. // Get all the rate data from the database.
  423. $result = db_query("SELECT * FROM {uc_taxes} ORDER BY weight");
  424. // Loop through each returned row.
  425. foreach ($result as $rate) {
  426. $rate->taxed_product_types = array();
  427. $rate->taxed_line_items = array();
  428. $rates[$rate->id] = $rate;
  429. }
  430. foreach (array('taxed_product_types', 'taxed_line_items') as $field) {
  431. $result = db_select('uc_' . $field, 't')->fields('t', array('tax_id', 'type'))->execute();
  432. foreach ($result as $record) {
  433. $rates[$record->tax_id]->{$field}[] = $record->type;
  434. }
  435. }
  436. }
  437. // Return a rate as specified.
  438. if ($rate_id) {
  439. return isset($rates[$rate_id]) ? $rates[$rate_id] : FALSE;
  440. }
  441. // Or return the whole shebang.
  442. else {
  443. return $rates;
  444. }
  445. }
  446. /**
  447. * Deletes a tax rate from the database.
  448. *
  449. * @param $rate_id
  450. * The ID of the tax rate to delete.
  451. */
  452. function uc_taxes_rate_delete($rate_id) {
  453. // Delete the tax rate record.
  454. db_delete('uc_taxes')
  455. ->condition('id', $rate_id)
  456. ->execute();
  457. db_delete('uc_taxed_product_types')
  458. ->condition('tax_id', $rate_id)
  459. ->execute();
  460. db_delete('uc_taxed_line_items')
  461. ->condition('tax_id', $rate_id)
  462. ->execute();
  463. // Delete the associated conditions if they have been saved to the database.
  464. rules_config_delete(array('uc_taxes_' . $rate_id));
  465. }
  466. /**
  467. * Calculates the taxes for an order based on enabled tax modules.
  468. *
  469. * @param $order
  470. * The full order object for the order want to calculate taxes for.
  471. *
  472. * @return
  473. * An array of taxes for the order.
  474. */
  475. function uc_taxes_calculate($order) {
  476. // Find any taxes specified by enabled modules.
  477. $taxes = module_invoke_all('uc_calculate_tax', $order);
  478. return $taxes;
  479. }
  480. /**
  481. * Calculates the amount and types of taxes that apply to an order.
  482. */
  483. function uc_taxes_uc_calculate_tax($order) {
  484. if (!is_object($order)) {
  485. return array();
  486. }
  487. if (empty($order->delivery_postal_code)) {
  488. $order->delivery_postal_code = $order->billing_postal_code;
  489. }
  490. if (empty($order->delivery_zone)) {
  491. $order->delivery_zone = $order->billing_zone;
  492. }
  493. if (empty($order->delivery_country)) {
  494. $order->delivery_country = $order->billing_country;
  495. }
  496. $order->taxes = array();
  497. foreach (uc_taxes_filter_rates($order) as $tax) {
  498. if ($line_item = uc_taxes_apply_tax($order, $tax)) {
  499. $order->taxes[$line_item->id] = $line_item;
  500. }
  501. }
  502. return $order->taxes;
  503. }
  504. /**
  505. * Calculates taxable amount for a single product.
  506. */
  507. function uc_taxes_apply_item_tax($item, $tax) {
  508. // Determine the product type.
  509. if (is_array($item->data) && isset($item->data['type'])) { // Saved in the order product data array.
  510. $type = $item->data['type'];
  511. }
  512. elseif (empty($item->nid)) { // "Blank-line" product.
  513. $type = 'blank-line';
  514. }
  515. elseif ($node = node_load($item->nid)) { // Use type of current node, if it exists.
  516. $type = $node->type;
  517. }
  518. else { // Default to generic product.
  519. $type = 'product';
  520. }
  521. // Determine whether this is a shippable product.
  522. if (is_array($item->data) && isset($item->data['shippable'])) { // Saved in the order product data array.
  523. $shippable = $item->data['shippable'];
  524. }
  525. elseif (empty($item->nid)) { // "Blank line" product.
  526. $shippable = $item->weight > 0;
  527. }
  528. elseif ($node = node_load($item->nid)) { // Use current node.
  529. $shippable = $node->shippable;
  530. }
  531. else {
  532. $shippable = variable_get('uc_product_shippable_' . $type); // Use default for this node type.
  533. }
  534. // Tax products if they are of a taxed type and if it is shippable if
  535. // the tax only applies to shippable products.
  536. if (in_array($type, $tax->taxed_product_types) && ($tax->shippable == 0 || $shippable == 1)) {
  537. return $item->price;
  538. }
  539. else {
  540. return FALSE;
  541. }
  542. }
  543. /**
  544. * Applies taxes to an order.
  545. *
  546. * @param $order
  547. * The order object being considered.
  548. * @param $tax
  549. * The tax rule calculating the amount.
  550. *
  551. * @return
  552. * The line item array representing the amount of tax.
  553. */
  554. function uc_taxes_apply_tax($order, $tax) {
  555. $amount = 0;
  556. $taxable_amount = 0;
  557. if (is_array($order->products)) {
  558. foreach ($order->products as $item) {
  559. $taxable_amount += $item->qty * uc_taxes_apply_item_tax($item, $tax);
  560. }
  561. }
  562. $taxed_line_items = $tax->taxed_line_items;
  563. if (is_array($order->line_items) && is_array($taxed_line_items)) {
  564. foreach ($order->line_items as $key => $line_item) {
  565. if ($line_item['type'] == 'tax') {
  566. // Don't tax old taxes.
  567. continue;
  568. }
  569. if (in_array($line_item['type'], $taxed_line_items)) {
  570. $callback = _uc_line_item_data($line_item['type'], 'tax_adjustment');
  571. if (isset($callback) && function_exists($callback)) {
  572. $taxable_amount += $callback($line_item['amount'], $order, $tax);
  573. }
  574. else {
  575. $taxable_amount += $line_item['amount'];
  576. }
  577. }
  578. }
  579. }
  580. if (in_array('tax', $taxed_line_items)) {
  581. // Tax taxes that were just calculated.
  582. foreach ($order->taxes as $other_tax) {
  583. $taxable_amount += $other_tax->amount;
  584. }
  585. }
  586. $amount = $taxable_amount * $tax->rate;
  587. if ($amount) {
  588. $line_item = (object) array(
  589. 'id' => $tax->id,
  590. 'name' => $tax->name,
  591. 'amount' => $amount,
  592. 'weight' => $tax->weight,
  593. 'summed' => 1,
  594. );
  595. $line_item->data = array(
  596. 'tax_rate' => $tax->rate,
  597. 'tax' => $tax,
  598. 'taxable_amount' => $taxable_amount,
  599. 'tax_jurisdiction' => $tax->name,
  600. );
  601. return $line_item;
  602. }
  603. }
  604. /**
  605. * Calculates the taxes that should be included in a product's display price.
  606. *
  607. * @param $product
  608. * The product whose included taxes are to be calculated.
  609. */
  610. function uc_taxes_get_included_tax($product, $order = NULL) {
  611. $amount = 0;
  612. $suffixes = array();
  613. foreach (uc_taxes_filter_rates($order) as $tax) {
  614. if ($tax->display_include) {
  615. $taxable = uc_taxes_apply_item_tax($product, $tax);
  616. if (!empty($taxable)) {
  617. $amount += $taxable * $tax->rate;
  618. $suffixes[$tax->inclusion_text] = $tax->inclusion_text;
  619. }
  620. }
  621. }
  622. return array($amount, $suffixes);
  623. }