t('Operations'));
// Loop through all the defined tax rates.
foreach (uc_taxes_rate_load() as $rate_id => $rate) {
// Build the operations links for the tax rate.
$ops = array(
l(t('edit'), 'admin/store/settings/taxes/'. $rate_id .'/edit'),
l(t('conditions'), CA_UI_PATH .'/uc_taxes_'. $rate_id .'/edit/conditions'),
l(t('clone'), 'admin/store/settings/taxes/'. $rate_id .'/clone'),
l(t('delete'), 'admin/store/settings/taxes/'. $rate_id .'/delete'),
);
// Add the row to the table.
$rows[] = array(
check_plain($rate->name),
$rate->rate * 100 .'%',
$rate->shippable ? t('Shippable products') : t('Any product'),
implode(', ', $rate->taxed_product_types),
implode(', ', $rate->taxed_line_items),
$rate->weight,
implode(' | ', $ops),
);
}
// Let the user know if no tax rates are defined.
if (empty($rows)) {
$rows[] = array(array('data' => t('No rates available.'), 'colspan' => 7));
}
// Build the output including the table and a link to add a new rate.
$output = theme('table', $header, $rows)
. l(t('Add a tax rate'), 'admin/store/settings/taxes/add');
return $output;
}
/**
* Build a form to add or edit a tax rate.
*
* @param $rate_id
* The ID of the tax rate to edit; leave NULL to add a new rate.
* @ingroup forms
* @see
* uc_taxes_form_validate()
* uc_taxes_form_submit()
*/
function uc_taxes_form($form_state, $rate_id = NULL) {
$form = array();
// If a rate ID was specified...
if ($rate_id) {
// Load the tax rate and set the page title.
$rate = uc_taxes_rate_load($rate_id);
drupal_set_title($rate->name);
}
$form['id'] = array(
'#type' => 'value',
'#value' => $rate_id,
);
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('This name will appear to the customer when this tax is applied to an order.
It will also be used to name the corresponding predicate for this rate.'),
'#default_value' => $rate_id ? $rate->name : '',
'#required' => TRUE,
);
$form['rate'] = array(
'#type' => 'textfield',
'#title' => t('Rate'),
'#description' => t('The tax rate as a percent or decimal. Examples: 6%, .06'),
'#default_value' => $rate_id ? $rate->rate : '',
'#size' => 15,
'#required' => TRUE,
);
$options = array(
'0' => t('Apply tax to any product regardless of its shipability.'),
1 => t('Apply tax to shippable products only.'),
);
$form['shippable'] = array(
'#type' => 'radios',
'#title' => t('Taxed products'),
'#options' => $options,
'#default_value' => $rate_id ? $rate->shippable : 0,
);
// TODO: Remove the need for a special case for product kit module.
$options = uc_product_type_names();
unset($options['product_kit']);
$options['blank-line'] = t('"Blank line" product');
$form['taxed_product_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Taxed product types'),
'#description' => t('Apply taxes to the specified product types/classes.'),
'#options' => $options,
'#default_value' => $rate_id ? $rate->taxed_product_types : array(),
);
$options = array();
foreach (_line_item_list() as $line_item) {
if (!in_array($line_item['id'], array('subtotal', 'tax_subtotal', 'total'))) {
$options[$line_item['id']] = $line_item['title'];
}
}
$form['taxed_line_items'] = array(
'#type' => 'checkboxes',
'#title' => t('Taxed line items'),
'#description' => t('Adds the checked line item types to the total before applying this tax.'),
'#options' => $options,
'#default_value' => $rate_id ? $rate->taxed_line_items : array(),
);
$form['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
'#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.'),
'#default_value' => $rate_id ? $rate->weight : 0,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#suffix' => l(t('Cancel'), 'admin/store/settings/taxes'),
);
return $form;
}
/**
* Ensure that tax rates are positive numbers.
*
* @see uc_taxes_form()
*/
function uc_taxes_form_validate($form, &$form_state) {
if (!empty($form_state['values']['rate']) && (floatval($form_state['values']['rate']) < 0)) {
form_set_error('rate', t('Rate must be a positive number. No commas and only one decimal point.'));
}
}
/**
* @see uc_taxes_form()
*/
function uc_taxes_form_submit($form, &$form_state) {
// Determine the decimal rate value.
if (strpos($form_state['values']['rate'], '%')) {
$form_state['values']['rate'] = floatval($form_state['values']['rate']) / 100;
}
else {
$form_state['values']['rate'] = floatval($form_state['values']['rate']);
}
// Build the rate object based on the form values and save it.
$rate = array(
'id' => $form_state['values']['id'],
'name' => $form_state['values']['name'],
'rate' => $form_state['values']['rate'],
'taxed_product_types' => array_filter($form_state['values']['taxed_product_types']),
'taxed_line_items' => array_filter($form_state['values']['taxed_line_items']),
'weight' => $form_state['values']['weight'],
'shippable' => $form_state['values']['shippable'],
);
uc_taxes_rate_save((object) $rate);
// Update the name of the associated predicate.
db_query("UPDATE {ca_predicates} SET title = '%s' WHERE pid = '%s'", $rate['name'], 'uc_taxes_'. $rate['id']);
// Display a message and redirect back to the overview.
drupal_set_message(t('Tax rate %name saved.', array('%name' => $form_state['values']['name'])));
$form_state['redirect'] = 'admin/store/settings/taxes';
}
/**
* Clone a tax rate.
*/
function uc_taxes_clone($rate_id) {
// Load the source rate object.
$rate = uc_taxes_rate_load($rate_id);
$name = $rate->name;
// Tweak the name and unset the rate ID.
$rate->name = t('Copy of !name', array('!name' => $rate->name));
$rate->id = NULL;
// Save the new rate.
$rate = uc_taxes_rate_save($rate);
// Clone the associated predicate as well.
if ($predicate = ca_load_predicate('uc_taxes_'. $rate_id)) {
$predicate['#pid'] = 'uc_taxes_'. $rate->id;
ca_save_predicate($predicate);
}
// Display a message and redirect back to the overview.
drupal_set_message(t('Tax rate %name cloned.', array('%name' => $name)));
drupal_goto('admin/store/settings/taxes');
}
/**
* Delete a tax rule.
*
* @ingroup forms
* @see uc_taxes_delete_submit()
*/
function uc_taxes_delete_form($form_state, $rate_id) {
$form = array();
// Bail if we got a bad rate ID.
if (!$rate = uc_taxes_rate_load($rate_id)) {
drupal_set_message(t('That tax rate does not exist.'), 'error');
drupal_goto('admin/store/settings/taxes');
}
$form['rate_id'] = array(
'#type' => 'value',
'#value' => $rate_id,
);
$form['name'] = array(
'#type' => 'value',
'#value' => $rate->name,
);
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.
If you just want this tax to no longer be applied to orders, consider disabling its predicate instead.'), t('Delete'), t('Cancel'));
}
/**
* @see uc_taxes_delete_form()
*/
function uc_taxes_delete_form_submit($form, &$form_state) {
// Delete the tax rate.
uc_taxes_rate_delete($form_state['values']['rate_id']);
// Display a message and redirect back to the overview.
drupal_set_message(t('Tax rate %name deleted.', array('%name' => $form_state['values']['name'])));
$form_state['redirect'] = 'admin/store/settings/taxes';
}