Display product prices incl. tax

Posts: 90
Joined: 02/14/2008
Bug FinderGetting busy with the Ubercode.Internationalizationizer

My suggestion has only sense if it goes into core, but I think there it belongs.

Targets:
- display product prices incl. VAT
- configuration in uc_store.module to turn it on/off
- uc_currency_prec: added support for .50 and .05 precision (off topic, but needed for some currencies)

These changes go into uc_store.module (beta5):

Configuration:

old (around line 1548):

<?php
  $form
['currency']['uc_currency_prec'] = array(
   
'#type' => 'select',
   
'#title' => t('Number of decimal places'),
   
'#options' => drupal_map_assoc(array(0, 1, 2)),
   
'#default_value' => variable_get('uc_currency_prec', 2),
  );
?>

new:

<?php
  $prec
= array(
   
'0' => t('No Decimals'),
   
'1' => t('One Decimal'),
   
'2' => t('Two Decimals'),
   
'.5' => t('Half Currencies'),
   
'.05' => '0.05',
  );
 
$form['currency']['uc_currency_prec'] = array(
   
'#type' => 'select',
   
'#title' => t('Number of decimal places/rounding of prices'),
   
'#options' => $prec,
   
'#default_value' => variable_get('uc_currency_prec', 2),
  );
 
$display_tax = array(
   
'0' => t('Don\'t display VAT'),
   
'1' => t('Display VAT always'),
  );
 
$form['currency']['uc_display_tax'] = array(
   
'#type' => 'select',
   
'#title' => t('Mode how to display tax'),
   
'#options' => $display_tax,
   
'#default_value' => variable_get('uc_display_tax', 2),
  );

?>

next three little functions I needed.
- uc_round(): because of this .50 Kč issue.
- uc_add_tax() is the thing we need ATM - it is simply an extract of uc_taxes.module
- uc_substr_tax() is the reverted version. I use it in a CCK field and computed field combo to add prices incl. VAT as a workaround. Could be used in core if price insert could be configured to "add prices with tax".

<?php
/**
* Round the displayed price according to the configuration.
* Supported are ATM 2 & 1 decimal, no decimal, half values
* and round on 0.05 currency units.
*/
function uc_round($value) {
 
$currency_prec = variable_get('uc_currency_prec', 2);
    switch (
$currency_prec) {
    case
'2': case '1': case '0': $round = round($value, $currency_prec);
      return
$round;
      break;
    default:
     
$prec_round = round(($value/$currency_prec), 0)*$currency_prec;
      return
$prec_round;
      break;
  }
}
/**
* As this function is just useful for inserting prices incl. tax
* the variable should be something like uc_insert_price_incl_tax
*/
function uc_substr_tax($value) {
  if (
variable_get('uc_display_tax', '0') == '1') {
   
$taxes = uc_taxes_get_rates();
    foreach (
$taxes as $tax){
     
$tax_rate += $tax->rate;
    }
   
$tax_rate++;
   
$value = $value/$tax_rate;
  }
  return
$value;
}

function
uc_add_tax($value) {
  if (
variable_get('uc_display_tax', '0') == '1') {
   
$taxes = uc_taxes_get_rates();
    foreach (
$taxes as $tax){
     
$tax_value += $value * $tax->rate;
    }
   
$value += $tax_value;
  }
 
// to avoid rounding issues with totals it is necessary already here to round.
 
$rounded_value = uc_round($value);
  return
$rounded_value;
}
?>

The $decimals thing to get a value 0, 1 or 2 in uc_currency_format() could be written different, but I would prefer that the program replaces 5.00 $ by 5,- $ and 5.5$ by 5[uc_currency_dec]50$.

In beta5 it is line 1963,
replace

<?php
  $format
.= number_format($value, variable_get('uc_currency_prec', 2), !is_null($dec) ? $dec : variable_get('uc_currency_dec', '.'), $thou ? variable_get('uc_currency_thou', ',') : '');

?>

with

<?php
  $val
= uc_round($value);
 
$test_val = (int)$val;
  if (
$val == $test_val) {
   
$decimals = '0';
  }
  else {
   
$decimals = '2';
  }

 
$format .= number_format(uc_round($value), $decimals, !is_null($dec) ? $dec : variable_get('uc_currency_dec', '.'), $thou ? variable_get('uc_currency_thou', ',') : '');
  if (
$decimals == '0') {
   
$format .= ',-';
  }
?>

This are all changes necessary to uc_store.module. The rest is to replace a couple of

uc_currency_format($value);

by
uc_currency_format(uc_add_tax($value));

By totals or subtotals I added the tax before to the items to prevent rounding issues.

Based on beta5 I found 13 places to add uc_add_tax() in 4 files:
uc_cart.module is affected 4 times:

- line 357 from
               . '<td class="cart-block-item-price">'. uc_currency_format($item->price) .'</td></tr>';
to
               . '<td class="cart-block-item-price">'. uc_currency_format(uc_add_tax($item->price)) .'</td></tr>';

- line 363 from
      $total += ($item->price) * $item->qty;
to
      $total += (uc_add_tax($item->price)) * $item->qty;

- line 1229 from     (tax can't be applied to subtotal at the end as it would produce rounding issues)
        $subtotal += $form['items'][$i]['#total'];
to
        $subtotal += uc_add_tax($form['items'][$i]['#total']);

- line 1237 from     (same as above)
        $data['total'][] = array('data' => uc_currency_format($form['items'][$i]['#total']), 'nowrap' => 'nowrap', 'class' => 'price');
to
        $data['total'][] = array('data' => uc_currency_format(uc_add_tax($form['items'][$i]['#total'])), 'nowrap' => 'nowrap', 'class' => 'price');

uc_cart_checkout_pane.inc one change:

- line 37 from
                  .'</td><td nowrap="nowrap">'. uc_currency_format($item->price * $item->qty) .'</td></tr>';

to
                  .'</td><td nowrap="nowrap">'. uc_currency_format(uc_add_tax($item->price) * $item->qty) .'</td></tr>';

uc_catalog.module one change:

- line 1138 from
          $product_table .= '<span class="catalog_grid_sell_price">'. uc_currency_format($product->sell_price) .'</span>';
to
          $product_table .= '<span class="catalog_grid_sell_price">'. uc_currency_format(uc_add_tax($product->sell_price)) .'</span>';

and finally uc_product.module 7 changes:

- line 1158 from
  return uc_currency_format($value);
to
  return uc_currency_format(uc_add_tax($value));

- line 2259 from
      $output .= t('List Price: !price', array('!price' => uc_currency_format($price)));
to
      $output .= t('List Price: !price', array('!price' => uc_currency_format(uc_add_tax($price))));

- line 2262 from
      $output .= t('Cost: !price', array('!price' => uc_currency_format($price)));
to
      $output .= t('Cost: !price', array('!price' => uc_currency_format(uc_add_tax($price))));

- line 2266 from
      $output .= t('Price: !price', array('!price' => uc_currency_format($price)));
to
      $output .= t('Price: !price', array('!price' => uc_currency_format(uc_add_tax($price))));

- line 2285 from
    $output .= uc_currency_format($price);
to
    $output .= uc_currency_format(uc_add_tax($price));

- line 2290 from
    $output .= t('Price: !price', array('!price' => uc_currency_format($price)));
to
    $output .= t('Price: !price', array('!price' => uc_currency_format(uc_add_tax($price))));

- line 2360 from
  $output .= uc_currency_format($price);
to
  $output .= uc_currency_format(uc_add_tax($price));

Sorry for the long post, but I think it is needed in more countries and as I think any site selling to end-users.

Tax problem: prices are inclusive tax By: coworks_dieter (47 replies) Wed, 02/20/2008 - 10:47