uc_tax_report.admin.inc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. <?php
  2. /**
  3. * @file
  4. * Displays sales tax report.
  5. */
  6. /**
  7. * Displays the sales tax report form and table.
  8. */
  9. function uc_tax_report_report_page($start_date = NULL, $end_date = NULL, $status = NULL) {
  10. // Use default report parameters if we don't detect values in the URL.
  11. if ($start_date == '') {
  12. $args = array(
  13. 'start_date' => mktime(0, 0, 0, date('n'), 1, date('Y') - 1),
  14. 'end_date' => REQUEST_TIME,
  15. 'status' => FALSE,
  16. );
  17. }
  18. else {
  19. $args = array(
  20. 'start_date' => $start_date,
  21. 'end_date' => $end_date,
  22. 'status' => explode(',', $status),
  23. );
  24. }
  25. // Pull the order statuses into a SQL friendly array.
  26. if ($args['status'] === FALSE) {
  27. $order_statuses = uc_reports_order_statuses();
  28. }
  29. else {
  30. $order_statuses = $args['status'];
  31. }
  32. // Build the header for the report table.
  33. $header = array(t('Tax Name'), t('Jurisdiction'), t('Tax rate'), t('Total taxable amount'), t('Total tax collected'));
  34. $rows = array();
  35. $csv_rows = array();
  36. $csv_rows[] = $header;
  37. // Query to get the tax line items in this date range.
  38. $result = db_query("SELECT ucoli.amount, ucoli.title, ucoli.data FROM {uc_orders} ucord LEFT JOIN {uc_order_statuses} ON order_status_id = order_status LEFT JOIN {uc_order_line_items} ucoli ON ucord.order_id = ucoli.order_id WHERE :start <= created AND created <= :end AND order_status IN (:statuses) AND ucoli.type = :type", array(':start' => $args['start_date'], ':end' => $args['end_date'], ':statuses' => $order_statuses, ':type' => 'tax'));
  39. // Add up the amounts by jurisdiction.
  40. $totals = array();
  41. $no_meta_totals = array();
  42. foreach ($result as $item) {
  43. $name = trim($item->title);
  44. $amount = floatval($item->amount);
  45. // Get the meta-data out of the serialized array.
  46. $data = unserialize($item->data);
  47. $jurisdiction = trim($data['tax_jurisdiction']);
  48. $taxable_amount = floatval($data['taxable_amount']);
  49. $rate = floatval($data['tax_rate']);
  50. // Make a line item in the report for each name/jurisdiction/rate.
  51. $key = strtolower($name) . strtolower($jurisdiction) . number_format($rate, 5);
  52. if (!empty($jurisdiction) && $amount && $taxable_amount) {
  53. // We have meta-data.
  54. if (empty($totals[$key])) {
  55. $totals[$key] = array(
  56. 'name' => $name,
  57. 'jurisdiction' => $jurisdiction,
  58. 'rate' => $rate,
  59. 'taxable_amount' => $taxable_amount,
  60. 'amount' => $amount,
  61. );
  62. }
  63. else {
  64. $totals[$key]['taxable_amount'] += $taxable_amount;
  65. $totals[$key]['amount'] += $amount;
  66. }
  67. }
  68. elseif ($amount) {
  69. // Old data: no meta-data was stored. Just report the amount collected.
  70. if (empty($no_meta_totals[$key])) {
  71. $no_meta_totals[$key] = array(
  72. 'name' => $name,
  73. 'amount' => $amount,
  74. );
  75. }
  76. else {
  77. $no_meta_totals[$key]['amount'] += $amount;
  78. }
  79. }
  80. }
  81. // Sort and make this into a report.
  82. ksort($totals);
  83. ksort($no_meta_totals);
  84. $taxable_amount = 0;
  85. $amount = 0;
  86. $star_legend = '';
  87. foreach ($totals as $line) {
  88. $row = array(
  89. $line['name'],
  90. $line['jurisdiction'],
  91. number_format($line['rate'] * 100, 3) . '%',
  92. theme('uc_price', array('price' => $line['taxable_amount'])),
  93. theme('uc_price', array('price' => $line['amount'])),
  94. );
  95. $rows[] = $row;
  96. // Remove HTML for CSV files.
  97. $row[3] = $line['taxable_amount'];
  98. $row[4] = $line['amount'];
  99. $csv_rows[] = $row;
  100. $taxable_amount += $line['taxable_amount'];
  101. $amount += $line['amount'];
  102. }
  103. foreach ($no_meta_totals as $line) {
  104. $row = array(
  105. $line['name'],
  106. '*',
  107. '*',
  108. '*',
  109. theme('uc_price', array('price' => $line['amount'])),
  110. );
  111. $rows[] = $row;
  112. // Remove HTML for CSV files.
  113. $row[4] = $line['amount'];
  114. $csv_rows[] = $row;
  115. $amount += $line['amount'];
  116. // We have at least one no-meta-data line. Explain why.
  117. $star_legend = t('* No information on jurisdiction, tax rate, or taxable amount is available for this line.');
  118. }
  119. // Add a totals line.
  120. $row = array(
  121. t('Total'),
  122. '',
  123. '',
  124. theme('uc_price', array('price' => $taxable_amount)),
  125. theme('uc_price', array('price' => $amount)),
  126. );
  127. $rows[] = $row;
  128. // Removes HTML for CSV files.
  129. $row[3] = $taxable_amount;
  130. $row[4] = $amount;
  131. $csv_rows[] = $row;
  132. // Cache the CSV export.
  133. module_load_include('inc', 'uc_reports', 'uc_reports.admin');
  134. $csv_data = uc_reports_store_csv('uc_tax_report', $csv_rows);
  135. // Build the page output holding the form, table, and CSV export link.
  136. $build['form'] = drupal_get_form('uc_tax_report_params_form', $args, $args['status']);
  137. $build['report'] = array(
  138. '#theme' => 'table',
  139. '#header' => $header,
  140. '#rows' => $rows,
  141. '#attributes' => array('width' => '100%', 'class' => array('uc-sales-table')),
  142. );
  143. if ($star_legend) {
  144. $build['legend'] = array(
  145. '#markup' => $star_legend,
  146. '#prefix' => '<div class="uc-reports-note"><p>',
  147. '#suffix' => '</p></div>',
  148. );
  149. }
  150. $build['export_csv'] = array(
  151. '#markup' => l(t('Export to CSV file.'), 'admin/store/reports/getcsv/' . $csv_data['report'] . '/' . $csv_data['user']),
  152. '#prefix' => '<div class="uc-reports-links">',
  153. '#suffix' => '</div>',
  154. );
  155. return $build;
  156. }
  157. /**
  158. * Form for parameters on the tax report.
  159. *
  160. * @see uc_tax_report_params_form_validate()
  161. * @see uc_tax_report_params_form_submit()
  162. * @ingroup forms
  163. */
  164. function uc_tax_report_params_form($form, &$form_state, $values) {
  165. $form['params'] = array(
  166. '#type' => 'fieldset',
  167. '#title' => t('Customize tax report parameters'),
  168. '#description' => t('Adjust these values and update the report to build your sales tax report. Once submitted, the report may be bookmarked for easy reference in the future.'),
  169. '#collapsible' => TRUE,
  170. '#collapsed' => FALSE,
  171. );
  172. $form['params']['start_date'] = array(
  173. '#type' => 'date',
  174. '#title' => t('Start date'),
  175. '#default_value' => array(
  176. 'month' => format_date($values['start_date'], 'custom', 'n'),
  177. 'day' => format_date($values['start_date'], 'custom', 'j'),
  178. 'year' => format_date($values['start_date'], 'custom', 'Y'),
  179. ),
  180. );
  181. $form['params']['end_date'] = array(
  182. '#type' => 'date',
  183. '#title' => t('End date'),
  184. '#default_value' => array(
  185. 'month' => format_date($values['end_date'], 'custom', 'n'),
  186. 'day' => format_date($values['end_date'], 'custom', 'j'),
  187. 'year' => format_date($values['end_date'], 'custom', 'Y'),
  188. ),
  189. );
  190. $options = array();
  191. foreach (uc_order_status_list() as $status) {
  192. $options[$status['id']] = $status['title'];
  193. }
  194. $stat = $values['status'];
  195. if ($stat === FALSE) {
  196. $stat = uc_reports_order_statuses();
  197. }
  198. $form['params']['status'] = array(
  199. '#type' => 'select',
  200. '#title' => t('Order statuses'),
  201. '#description' => t('Only orders with selected statuses will be included in the report.') . '<br />' . t('Hold Ctrl + click to select multiple statuses.'),
  202. '#options' => $options,
  203. '#default_value' => $stat,
  204. '#multiple' => TRUE,
  205. '#size' => 5,
  206. );
  207. $form['params']['actions'] = array('#type' => 'actions');
  208. $form['params']['actions']['submit'] = array(
  209. '#type' => 'submit',
  210. '#value' => t('Update report'),
  211. );
  212. return $form;
  213. }
  214. /**
  215. * Ensures an order status is selected.
  216. *
  217. * @see uc_tax_report_params_form()
  218. * @see uc_tax_report_params_form_submit()
  219. */
  220. function uc_tax_report_params_form_validate($form, &$form_state) {
  221. if (empty($form_state['values']['status'])) {
  222. form_set_error('status', t('You must select at least one order status.'));
  223. }
  224. }
  225. /**
  226. * Form submission handler for uc_tax_report_params_form().
  227. *
  228. * @see uc_tax_report_params_form()
  229. * @see uc_tax_report_params_form_validate()
  230. */
  231. function uc_tax_report_params_form_submit($form, &$form_state) {
  232. // Build the start and end dates from the form.
  233. $start_date = mktime(0, 0, 0, $form_state['values']['start_date']['month'], $form_state['values']['start_date']['day'], $form_state['values']['start_date']['year']);
  234. $end_date = mktime(23, 59, 59, $form_state['values']['end_date']['month'], $form_state['values']['end_date']['day'], $form_state['values']['end_date']['year']);
  235. $args = array(
  236. $start_date,
  237. $end_date,
  238. implode(',', array_keys($form_state['values']['status'])),
  239. );
  240. $form_state['redirect'] = 'admin/store/reports/tax/' . implode('/', $args);
  241. }