Small improvement to uc_taxes: tax based on shipping status (shippable or not)

Posts: 5
Joined: 06/29/2008

Howdy folks - a client needed to be able to apply tax only to some products and not others (based on whether they are shippable or not). Not wanting to create new node types (product classes) and convert a bunch of products/CCK/template settings, I modified uc_taxes.module. Seems like that might be useful to other people, so here are the modifications (I am terrible at making patches).

A quick note: would it make sense to put a workflow ng event in uc_taxes_action_apply_tax(), with the product node and the tax object as arguments? That would allow users to set up a number of conditions wherein tax is applied or not without bloating up the uc_taxes module (as I have done). But I don't understand workflow ng well enough yet to do it myself - can you have a workflow event within a workflow event?

My line numbers may be just a bit off.

MODIFY uc_taxes_workflow.inc
line 88 - uc_taxes_action_apply_tax()

      if (in_array($node->type, $tax->taxed_product_types)) {
        if ($tax->shippable == 0 || ($tax->shippable == 1 && $node->shippable == 1)) {
          $amount += $item->price * $item->qty * $tax->rate;
        }
      }

MODIFY database table uc_taxes
Add a new column to this table: shippable [tinyint(1)] [default value: 0]

MODIFY uc_taxes.module
line 183 - uc_taxes_admin_settings

$header = array(t('Name'), t('Rate'), t('Taxed product types'), t('Tax only shippable?'), t('Taxed line items'), t('Weight'), array('data' => t('Actions'), 'colspan' => 3));

line 189 - same function

$rows[] = array($rule->name, $rule->rate * 100 .'%', implode(', ', $rule->taxed_product_types), $rule->shippable ? t('Yes') : t('--'), implode(', ', $rule->taxed_line_items), $rule->weight, l(t('edit'), 'admin/store/settings/taxes/edit/'. $rule->id), l(t('copy'), 'admin/store/settings/taxes/copy/'. $rule->id), l(t('delete'), 'admin/store/settings/taxes/delete/'. $rule->id));

line 236 - uc_taxes_form() - new code

  $shippable_options = array('0' => t('Tax all products regardless of shipping status'), 1 => t('Tax only shippable products'));
  $form['shippable'] = array('#type' => 'radios',
    '#title' => t('Tax products based on shipping status?'),
    '#multiple' => true,
    '#options' => $shippable_options,
    '#default_value' => $form_values['shippable'],
  );

line 281 - uc_taxes_form_submit()

db_query("UPDATE {uc_taxes} SET name = '%s', rate = %f, taxed_product_types = '%s', taxed_line_items = '%s', weight = %d, shippable = %d WHERE id = %d",
        $form_values['name'], $rate, serialize(array_filter($form_values['taxed_product_types'])), serialize(array_filter($form_values['taxed_line_items'])), $form_values['weight'], $form_values['shippable'], $form_values['id']
      );

line 286 - same function

      db_query("INSERT INTO {uc_taxes} (id, name, rate, taxed_product_types, taxed_line_items, weight, shippable) VALUES (%d, '%s', %f, '%s', '%s', %d, %d)",
        db_next_id('{uc_taxes}_id'), $form_values['name'], $rate, serialize(array_filter($form_values['taxed_product_types'])), serialize(array_filter($form_values['taxed_line_items'])), $form_values['weight'], $form_values['shippable']
      );

line 302 - uc_taxes_copy()

  db_query("INSERT INTO {uc_taxes} (id, name, rate, taxed_product_types, taxed_line_items, weight, shippable) VALUES (%d, '%s', %f, '%s', '%s', %d, %d)",
    db_next_id('{uc_taxes}_id'), t('Copy of @rule', array('%rule' => $rule['name'])), $rule['rate'], $rule['taxed_product_types'], $rule['taxed_line_items'], $rule['weight'], $rule['shippable']
  );

Posts: 5621
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

+1 to this idea... not sure where it should fit in, but this is great for doing something like charging tax when mailing someone a book but not when they purchase an eBook or site membership.