Search This Blog For Stuff

Loading...

Monday, August 10, 2009

BambooInvoice Canadian Tax System

UPDATE: Our good friend Derek Allard (whose brainchild is said BambooInvoice) has informed me over at the BI Forums that an update is forthcoming which will include a much more versitile taxation system. /me wonders what other delicious treats will be bundled with this new incarnation... shall it even be 1.0 ??!

--==:[0000.0000]:==--

Not just for Canadians, but anyone who may want to use one, the other or both taxes on a single line item in Bamboo Invoice.

**WARNING** This hack is not for the faint of heart, I may have missed something in the chronicling of this adventure and I can't guarantee this will work for you in any way.

In case you haven't heard, BambooInvoice is only the slickest open source online invoicing system built with CodeIgnitor.

This mod is quite a hack, but the principal is to double the 'taxable' functionality for each line item, thus having a taxable1 and taxable2 for each item on the invoice.

To pull this off, modify the existing bamboo_invoice_items.taxable field to be called bamboo_invoice_items.taxable1 and add another field of INT(1) or BOOLEAN (if you will) called bamboo_invoice_items.taxable2

...Then make the following changes to the following files.


***********
[/bamboo_system_files/application/controllers/invoices.php]
-> Line 141:

foreach ($items as $item)
{
//$taxable = (isset($item['taxable']) && $item['taxable'] == 1) ? 1 : 0;
$taxable1 = (isset($item['taxable1']) && $item['taxable1'] == 1) ? 1 : 0;
$taxable2 = (isset($item['taxable2']) && $item['taxable2'] == 1) ? 1 : 0;
$sub_amount = $item['quantity'] * $item['amount'];
$amount += $sub_amount;
$tax1_amount += $sub_amount * (($tax1_rate)/100) * $taxable1;
$tax2_amount += $sub_amount * (($tax2_rate)/100) * $taxable2;
}

echo '{"amount" : "'.number_format($amount, 2, $this->config->item('currency_decimal'), '').'", "tax1_amount" : "'.number_format($tax1_amount, 2, $this->config->item('currency_decimal'), '').'", "tax2_amount" : "'.number_format($tax2_amount, 2, $this->config->item('currency_decimal'), '').'", "total_amount" : "'.number_format($amount + $tax1_amount+$tax2_amount, 2, $this->config->item('currency_decimal'), '').'"}';
}


-> Line 225:

$amount = 0;
foreach ($items as $item)
{
$taxable1 = (isset($item['taxable1']) && $item['taxable1'] == 1) ? 1 : 0;
$taxable2 = (isset($item['taxable2']) && $item['taxable2'] == 1) ? 1 : 0;

$invoice_items = array(
'invoice_id' => $invoice_id,
'quantity' => $item['quantity'],
'amount' => $item['amount'],
'work_description' => $item['work_description'],
'taxable1' => $taxable1,
'taxable2' => $taxable2
);

$this->invoices_model->addInvoiceItem($invoice_items);
}

redirect('invoices/view/'.$invoice_id);

-> Line 426:
// add them back
$items = $this->input->post('items');
foreach ($items as $item)
{
$taxable1 = (isset($item['taxable1']) && $item['taxable1'] == 1) ? 1 : 0;
$taxable2 = (isset($item['taxable2']) && $item['taxable2'] == 1) ? 1 : 0;

$invoice_items = array(
'invoice_id' => $invoice_id,
'quantity' => $item['quantity'],
'amount' => $item['amount'],
'work_description' => $item['work_description'],
'taxable1' => $taxable1,
'taxable2' => $taxable2
);

$this->invoices_model->addInvoiceItem($invoice_items);
}

// give a session telling them it worked

-> Line 550:

$amount = 0;
foreach ($items as $item)
{
$taxable1 = (isset($item['taxable1']) && $item['taxable1'] == 1) ? 1 : 0;
$taxable2 = (isset($item['taxable2']) && $item['taxable2'] == 1) ? 1 : 0;

$invoice_items = array(
'invoice_id' => htmlspecialchars($invoice_id),
'quantity' => htmlspecialchars($item['quantity']),
'amount' => htmlspecialchars($item['amount']),
'work_description' => htmlspecialchars($item['work_description']),
'taxable1' => htmlspecialchars($taxable1),
'taxable2' => htmlspecialchars($taxable2)
);

$this->invoices_model->addInvoiceItem($invoice_items);
}
}

***********

[/bamboo_system_files/application/language/english/bamboo_lang.php]
-> Line 108:
$lang['invoice_item'] = 'Item';
$lang['invoice_item_no_tax1'] = 'GST Exempt';
$lang['invoice_item_no_tax2'] = 'PST Exempt';
$lang['invoice_last_used'] = 'last number used ';
***********

[/bamboo_system_files/application/models/invoices_model.php]
-> Line 92: ...replace the whole function...
function getSingleInvoice($invoice_id)
{
$this->db->select('invoices.*, clients.name, clients.address1, clients.address2, clients.city, clients.country, clients.province, clients.website, clients.postal_code, clients.tax_code');
$this->db->select('(SELECT SUM('.$this->db->dbprefix('invoice_payments').'.amount_paid) FROM '.$this->db->dbprefix('invoice_payments').' WHERE '.$this->db->dbprefix('invoice_payments').'.invoice_id=' . $invoice_id . ') AS amount_paid', FALSE);
$this->db->select('TO_DAYS('.$this->db->dbprefix('invoices').'.dateIssued) - TO_DAYS(curdate()) AS daysOverdue', FALSE);
$this->db->select('(SELECT SUM('.$this->db->dbprefix('invoice_items').'.amount * '.$this->db->dbprefix('invoice_items').'.quantity) FROM '.$this->db->dbprefix('invoice_items').' WHERE '.$this->db->dbprefix('invoice_items').'.invoice_id=' . $invoice_id . ') AS total_notax', FALSE);


$this->db->select('(SELECT ROUND(SUM(SubTotal_Tax1) * tax1, 3) as total_tax1
FROM (SELECT tax1, amt * qty AS SubTotal_Tax1
FROM (SELECT '.$this->db->dbprefix('invoice_items').'.quantity AS qty, '.$this->db->dbprefix('invoice_items').'.amount AS amt, ('.$this->db->dbprefix('invoices').'.tax1_rate / 100) as tax1
FROM '.$this->db->dbprefix('invoices').' LEFT JOIN '.$this->db->dbprefix('invoice_items').' ON '.$this->db->dbprefix('invoices').'.id = '.$this->db->dbprefix('invoice_items').'.invoice_id WHERE '.$this->db->dbprefix('invoice_items').'.invoice_id =' . $invoice_id . ' AND '.$this->db->dbprefix('invoice_items').'.taxable1 =1 ) AS tmp_Tax_Total ) AS tmp_Total) AS total_tax1', FALSE);


$this->db->select('(SELECT ROUND(SUM(SubTotal_tax2) * tax2, 3) as total_tax2
FROM (SELECT tax2, amt * qty AS SubTotal_tax2
FROM (SELECT '.$this->db->dbprefix('invoice_items').'.quantity AS qty, '.$this->db->dbprefix('invoice_items').'.amount AS amt, ('.$this->db->dbprefix('invoices').'.tax2_rate / 100) as tax2
FROM '.$this->db->dbprefix('invoices').' LEFT JOIN '.$this->db->dbprefix('invoice_items').' ON '.$this->db->dbprefix('invoices').'.id = '.$this->db->dbprefix('invoice_items').'.invoice_id WHERE '.$this->db->dbprefix('invoice_items').'.invoice_id =' . $invoice_id . ' AND '.$this->db->dbprefix('invoice_items').'.taxable2 =1 ) AS tmp_Tax_Total ) AS tmp_Total) AS total_tax2', FALSE);

$this->db->select('(SELECT SUM(total_notax + COALESCE(total_tax1,0) + COALESCE(total_tax2,0))) AS total_with_tax');


$this->db->join('clients', 'invoices.client_id = clients.id');
$this->db->join('invoice_items', 'invoices.id = invoice_items.invoice_id', 'left');
$this->db->join('invoice_payments', 'invoices.id = invoice_payments.invoice_id', 'left');
$this->db->groupby('invoices.id');
$this->db->where('invoices.id', $invoice_id);

return $this->db->get('invoices');
}

// --------------------------------------------------------------------

-> Line 238:
$this->db->select('TO_DAYS('.$this->db->dbprefix('invoices').'.dateIssued) - TO_DAYS(curdate()) AS daysOverdue', FALSE);
$this->db->select('(SELECT SUM('.$this->db->dbprefix('invoice_items').'.amount * '.$this->db->dbprefix('invoice_items').'.quantity) FROM '.$this->db->dbprefix('invoice_items').' WHERE '.$this->db->dbprefix('invoice_items').'.invoice_id='.$this->db->dbprefix('invoices').'.id) AS subtotal', FALSE);

$this->db->join('clients', 'invoices.client_id = clients.id');

***********

[/bamboo_system_files/application/views/invoices/edit.php]
-> Line 42:
<th><?php echo $this->lang->line('invoice_work_description');?></th>
<th><?php echo $this->lang->line('invoice_taxable1');?></th>
<th><?php echo $this->lang->line('invoice_taxable2');?></th>
<th><?php echo $this->lang->line('invoice_amount_item');?></th>
-> Line 64:
</td>
<td><p><label><input type="checkbox" name="items[<?php echo $item_count;?>][taxable1]" value="1" onclick="recalculate_items();" <?php if ($item->taxable1 == 1) {echo 'checked="checked" ';}?>/><span><?php echo $this->lang->line('invoice_taxable1');?>?</span></label></p></td>
<td><p><label><input type="checkbox" name="items[<?php echo $item_count;?>][taxable2]" value="1" onclick="recalculate_items();" <?php if ($item->taxable2 == 1) {echo 'checked="checked" ';}?>/><span><?php echo $this->lang->line('invoice_taxable2');?>?</span></label></p></td>
<td nowrap="nowrap"><p><label><span><?php echo $this->lang->line('invoice_amount');?></span><?php echo $this->settings_model->get_setting('currency_symbol');?><input type="text" id="amount" name="items[<?php echo $item_count;?>][amount]" size="5" value="<?php echo $item->amount;?>" onkeyup="recalculate_items();" value="" /></label></p></td>

***********

[/bamboo_system_files/application/views/invoices/newinvoice.php]
-> Line 38:
<th><?php echo $this->lang->line('invoice_work_description');?></th>
<th><?php echo $tax1_desc;?></th>
<th><?php echo $tax2_desc;?></th>
<th><?php echo $this->lang->line('invoice_amount_item');?></th>

-> Line 54:
</td>
<td><p><label><input type="checkbox" name="items[1][taxable1]" value="1" onclick="recalculate_items();" <?php if ($row->tax_status) {echo 'checked="checked" ';}?>/><span><?php echo $this->lang->line('invoice_taxable1');?>?</span></label></p></td>
<td><p><label><input type="checkbox" name="items[1][taxable2]" value="1" onclick="recalculate_items();" <?php if ($row->tax_status) {echo 'checked="checked" ';}?>/><span><?php echo $this->lang->line('invoice_taxable2');?>?</span></label></p></td> <td nowrap="nowrap"><p><label><span><?php echo $this->lang->line('invoice_amount');?></span><?php echo $this->settings_model->get_setting('currency_symbol');?><input type="text" id="amount" name="items[1][amount]" size="5" value="0.00" onkeyup="recalculate_items();" value="" /></label></p></td>
<td> </td>
***********

[/bamboo_system_files/application/views/invoices/view.php]
-> Line 169:
<td><?php echo auto_typography($item->work_description);?></td>
<td><p><?php echo $this->settings_model->get_setting('currency_symbol') . str_replace('.', $this->config->item('currency_decimal'), $item->amount);?> <?php if ($item->taxable1 == 0){echo '(' . $this->lang->line('invoice_item_no_tax1') . ')';}?>
<?php if ($item->taxable2 == 0){echo '(' . $this->lang->line('invoice_item_no_tax2') . ')';}?></p></td>
<td><p><?php echo $this->settings_model->get_setting('currency_symbol') . number_format($item->quantity * $item->amount, 2, $this->config->item('currency_decimal'), '');?></p></td>
***********

[/js/createinvoice.js]
-> Line 84:
theInput.setAttribute('type', 'checkbox');
theInput.setAttribute('name', 'items['+item_count+'][taxable1]');

if (taxable)

-> Line 105: ...insert the following...

var td = document.createElement('td');
var p = document.createElement('p');
var label = document.createElement('label');
var span = document.createElement('span');
var theData = document.createTextNode(lang_taxable);
var theInput = document.createElement('input');
theInput.setAttribute('type', 'checkbox');
theInput.setAttribute('name', 'items['+item_count+'][taxable2]');

if (taxable)
{
theInput.setAttribute('checked', 'checked');
}
else
{
theInput.checked = false;
}

theInput.setAttribute('value', '1');
theInput.setAttribute('onclick', 'recalculate_items();');
span.appendChild(theData);
label.appendChild(span);
label.appendChild(theInput);
p.appendChild(label);
td.appendChild(p);
row.appendChild(td);



Digg Technorati del.icio.us Stumbleupon Reddit Blinklist Furl Spurl Yahoo Simpy

0 user responses:

Video Bar

Loading...

Usage Policy

You are free to view, read, click and use the features of this blog as outlined in the terms & services agreement found here. All post data is copyright it's original owner as indicated or the blog editor. All registered trademarks and copy protected images or text found on this site belong to their respective owner in their copy protected country. The only one responsible in any way for any thing related to the content found herein is you - for it is you whom is interpreting it.