commerce_reports_tax.module in Commerce Reporting 7.4
Same filename and directory in other branches
Module file for Commerce Reports Tax.
File
modules/tax/commerce_reports_tax.moduleView source
<?php
/**
* @file
* Module file for Commerce Reports Tax.
*/
/**
* Implements hook_help().
*/
function commerce_reports_tax_help($path, $arg) {
switch ($path) {
case 'admin/commerce/reports/tax':
return '<p>' . t('Here you can see reports about the tax gathered by your store.') . '</p>';
}
}
/**
* Implements hook_views_api().
*/
function commerce_reports_tax_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'commerce_reports_tax') . '/includes/views',
);
}
/**
* Implements hook_menu().
*/
function commerce_reports_tax_menu() {
$items = array();
$items['admin/commerce/config/tax-reports'] = array(
'title' => 'Tax reports settings',
'description' => 'Configure tax reports settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_reports_tax_form',
),
'access arguments' => array(
'configure commerce tax reports',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'commerce_reports_tax.admin.inc',
);
$items['admin/commerce/config/tax-reports/generate'] = array(
'title' => 'Generate tax report',
'page callback' => 'commerce_reports_tax_generate_callback',
'access arguments' => array(
'configure commerce tax reports',
),
'type' => MENU_CALLBACK,
'file' => 'commerce_reports_tax.admin.inc',
);
return $items;
}
/**
* Implements hook_menu_alter().
*/
function commerce_reports_tax_menu_alter(&$items) {
$items['admin/commerce/reports/tax']['title'] = 'Tax';
$items['admin/commerce/reports/tax']['type'] = MENU_LOCAL_TASK;
$items['admin/commerce/reports/tax']['weight'] = 50;
if (empty($items['admin/commerce/reports'])) {
$items['admin/commerce/reports'] = array(
'title' => 'Reports',
'description' => 'View reports for your store.',
'access arguments' => array(
'access commerce tax reports',
),
'page callback' => 'drupal_goto',
'page arguments' => array(
'admin/commerce/reports/tax',
),
'weight' => 50,
);
}
}
/**
* Implements hook_permission().
*/
function commerce_reports_tax_permission() {
return array(
'access commerce tax reports' => array(
'title' => t('Access commerce tax reports'),
),
'configure commerce tax reports' => array(
'title' => t('Configure commerce tax reports'),
),
);
}
/**
* Implements hook_commerce_reports_dashboard().
*/
function commerce_reports_tax_commerce_reports_dashboard() {
return array(
'commerce_reports_tax' => array(
'title' => t('Taxes'),
'type' => COMMERCE_REPORTS_DASHBOARD_BROAD_BLOCK,
'report' => array(
'title' => t('Tax reports'),
'path' => 'admin/commerce/reports/tax',
),
'sections' => array(
'default' => array(
'module' => 'commerce_reports_tax',
'block' => 'commerce_reports_tax',
),
),
'weight' => 5,
),
);
}
/**
* Implements hook_commerce_reports_dashboard_alter().
*/
function commerce_reports_tax_commerce_reports_dashboard_alter(&$info) {
$info['customer_statistics']['weight'] = 10;
$info['sales_statistics']['weight'] = 300;
$info['billing_information']['type'] = COMMERCE_REPORTS_DASHBOARD_ROW;
}
/**
* Implements hook_block_info().
*
* Defines the custom blocks defined by commerce_reports_tax.
*/
function commerce_reports_tax_block_info() {
return array(
'commerce_reports_tax' => array(
'info' => t('Commerce Tax Reports'),
),
);
}
/**
* Implements hook_block_view().
*
* Implementation of the dashboard block used in commerce_reports.
*/
function commerce_reports_tax_block_view($delta = '') {
module_load_include('inc', 'commerce_reports_tax', 'commerce_reports_tax.admin');
switch ($delta) {
case 'commerce_reports_tax':
return commerce_reports_tax_table();
}
}
/**
* Implements hook_entity_insert().
*/
function commerce_reports_tax_entity_insert($entity, $type) {
if ($type == 'commerce_order' && in_array($entity->status, variable_get('commerce_reports_tax_order_statuses', array(
'pending',
'processing',
'completed',
)))) {
commerce_reports_tax_order_save($entity);
}
}
/**
* Implements hook_entity_update().
*/
function commerce_reports_tax_entity_update($entity, $type) {
if ($type == 'commerce_order' && isset($entity->original)) {
// Mark original entity for easy reference.
$original = $entity->original;
// Check the updated status against statuses in settings.
$order_current_status = in_array($entity->status, variable_get('commerce_reports_tax_order_statuses', array(
'pending',
'processing',
'completed',
)));
// Check the original status, so we know if we need to remove last record.
$order_previous_status = in_array($original->status, variable_get('commerce_reports_tax_order_statuses', array(
'pending',
'processing',
'completed',
)));
// The order changed to a order status we're interested in, but did not
// previously have a watched status. Create a new record.
if ($order_current_status && !$order_previous_status) {
commerce_reports_tax_order_save($entity);
}
elseif (!$order_current_status && $order_previous_status) {
commerce_reports_tax_order_delete($entity->order_id);
}
elseif ($order_current_status && $order_previous_status && $original->commerce_order_total != $entity->commerce_order_total) {
commerce_reports_tax_order_save($entity);
}
}
}
/**
* Implements hook_entity_delete().
*/
function commerce_reports_tax_entity_delete($entity, $type) {
if ($type == 'commerce_order') {
commerce_reports_tax_order_delete($entity->order_id);
}
}
/**
* Returns the order statuses that should be taken into account.
*/
function commerce_reports_tax_order_statuses() {
return variable_get('commerce_reports_tax_order_generate_statuses', array(
'pending',
'completed',
));
}
/**
* Generate historic tax information.
*/
function commerce_reports_tax_generate() {
$batch = array(
'title' => t('Generating tax report'),
'operations' => array(
array(
'_commerce_reports_tax_generate',
array(),
),
),
'finished' => '_commerce_reports_tax_finished',
'file' => drupal_get_path('module', 'commerce_reports_tax') . '/commerce_reports_tax.batch.inc',
);
batch_set($batch);
}
/**
* Deletes the tax information of multiple orders.
*/
function commerce_reports_tax_order_delete_multiple($order_ids = array()) {
return db_query("DELETE FROM {commerce_reports_tax} WHERE order_id IN (:order_ids)", array(
':order_ids' => $order_ids,
));
}
/**
* Deletes the tax information of an order.
*/
function commerce_reports_tax_order_delete($order_id) {
return commerce_reports_tax_order_delete_multiple(array(
$order_id,
));
}
/**
* Returns all reported taxes.
*/
function commerce_reports_tax($start, $end) {
$results = db_query("SELECT crt.tax_rate AS name, ctr.display_title AS title, crt.currency_code, SUM(crt.taxable) AS taxable, SUM(crt.taxed) AS taxed FROM {commerce_reports_tax} crt LEFT JOIN {commerce_tax_rate} ctr ON crt.tax_rate = ctr.name LEFT JOIN {commerce_order} co ON crt.order_id = co.order_id WHERE co.created BETWEEN :start AND :end GROUP BY crt.tax_rate, crt.currency_code", array(
':start' => $start,
':end' => $end,
));
$rows = array();
while ($result = $results
->fetchAssoc()) {
$rows[$result['name']] = array(
$result['title'],
commerce_currency_format($result['taxable'], $result['currency_code']),
commerce_currency_format($result['taxed'], $result['currency_code']),
);
}
return $rows;
}
/**
* Stores the tax information of an order.
*
* If the order has already been processed in the past it will compare the
* information in the database with the generated information and update
* accordingly.
*/
function commerce_reports_tax_order_save($order) {
/** @var EntityDrupalWrapper $wrapper */
$wrapper = entity_metadata_wrapper('commerce_order', $order);
$order_id = $wrapper->order_id
->value();
// Loop through all line items and get taxes from taxable line items.
$applied_taxes = array();
foreach ($wrapper->commerce_line_items as $line_item_wrapper) {
if ($tax_rates = _commerce_reports_tax_get_tax_rates($line_item_wrapper)) {
// Taxable.
$taxable = $line_item_wrapper->commerce_total
->value();
// Taxed.
foreach ($tax_rates as $tax_rate) {
$taxed = commerce_price_component_total($taxable, $tax_rate['price_component']);
$id = $tax_rate['name'] . $order_id . $taxed['currency_code'];
// Create fresh record if it doesn't exist.
if (empty($applied_taxes[$id])) {
$applied_taxes[$id] = new stdClass();
$applied_taxes[$id]->tax_rate = $tax_rate['name'];
$applied_taxes[$id]->order_id = $order_id;
$applied_taxes[$id]->currency_code = $taxed['currency_code'];
$applied_taxes[$id]->taxable = 0;
$applied_taxes[$id]->taxed = 0;
}
// Increase the amounts.
$applied_taxes[$id]->taxable += $taxable['amount'];
$applied_taxes[$id]->taxed += round($taxed['amount']);
}
}
else {
// TODO: Keep track of amount where taxes were not applied?
}
}
// Check to see if save records exist before saving new record.
$result = db_query("SELECT tax_rate, order_id, currency_code, taxable, taxed FROM {commerce_reports_tax} WHERE order_id = :order_id", array(
':order_id' => $order->order_id,
));
// If we have records, update the existing, else add new.
if ($result
->rowCount() > 0) {
// Update record.
while ($row = $result
->fetchAssoc()) {
$tax_record_id = $row['tax_rate'] . $row['order_id'] . $row['currency_code'];
drupal_write_record('commerce_reports_tax', $applied_taxes[$tax_record_id], array(
'tax_rate',
'order_id',
'currency_code',
));
}
}
else {
// Insert any of the remaining applied taxes.
foreach ($applied_taxes as $tax) {
drupal_write_record('commerce_reports_tax', $tax);
}
}
}
/**
* Helper function for getting applied tax rate from line item wrapper.
*
* @param EntityDrupalWrapper $line_item_wrapper
* The wrapped line item entity.
*
* @return array
* An array set of tax rates from given line item.
*/
function _commerce_reports_tax_get_tax_rates(EntityDrupalWrapper $line_item_wrapper) {
$commerce_total_data = $line_item_wrapper->commerce_total->data
->value();
$tax_rates = array();
foreach ($commerce_total_data['components'] as $component) {
if (!empty($component['price']['data']['tax_rate']['name'])) {
$tax_rates[$component['price']['data']['tax_rate']['name']] = commerce_tax_rate_load($component['price']['data']['tax_rate']['name']);
}
}
return $tax_rates;
}
/**
* Returns the order states to report on.
*
* @return array
* Array of order states for Views to filter on.
*/
function commerce_reports_tax_reportable_order_states() {
if (function_exists('commerce_reports_reportable_order_states')) {
return commerce_reports_reportable_order_states();
}
$cache =& drupal_static(__FUNCTION__, array());
if (empty($cache)) {
$report_states = array(
'pending',
'completed',
);
// Validate states.
$order_states = commerce_order_states();
foreach ($report_states as $state) {
if (!in_array($state, $order_states)) {
unset($report_states[$state]);
}
}
// Use array_combine to match View's 'value' => 'value',
$cache = array_combine($report_states, $report_states);
}
return $cache;
}