Some updates to invoice

This commit is contained in:
Deon George 2013-06-11 14:30:13 +10:00
parent 114ac8eb38
commit 25a47cac3a
6 changed files with 273 additions and 316 deletions

View File

@ -44,10 +44,13 @@ class Auth_OSB extends Auth_ORM {
if ($mmto->loaded()) { if ($mmto->loaded()) {
// Check that the token is for this URI // Check that the token is for this URI
$mo = ORM::factory('Module',array('name'=>Request::current()->controller())); $mo = ORM::factory('Module',array('name'=>Request::current()->controller()));
$mmo = ORM::factory('Module_Method',array( $mmo = $mo->module_method
'module_id'=>$mo->id, ->where_open()
'name'=>strtolower(Request::current()->directory() ? sprintf('%s:%s',Request::current()->directory(),Request::current()->action()) : Request::current()->action()) ->where('name','=',strtolower(Request::current()->directory() ? sprintf('%s:%s',Request::current()->directory(),Request::current()->action()) : Request::current()->action()))
)); // @todo No longer required after all method names have been colon delimited
->or_where('name','=',strtolower(Request::current()->directory() ? sprintf('%s_%s',Request::current()->directory(),Request::current()->action()) : Request::current()->action()))
->where_close()
->find();
// Ignore the token if this is not the right method. // Ignore the token if this is not the right method.
if ($mmo->id == $mmto->method_id) { if ($mmo->id == $mmto->method_id) {

View File

@ -10,129 +10,5 @@
* @license http://dev.osbill.net/license.html * @license http://dev.osbill.net/license.html
*/ */
class Controller_Invoice extends Controller_TemplateDefault { class Controller_Invoice extends Controller_TemplateDefault {
protected $secure_actions = array(
'download'=>TRUE,
'list'=>TRUE,
'view'=>TRUE,
);
/**
* Show a list of invoices
*/
public function action_list() {
Block::add(array(
'title'=>sprintf('%s: %s - %s',_('Invoices For'),$this->ao->accnum(),$this->ao->name(TRUE)),
'body'=>Table::display(
$this->ao->invoice->find_all(),
25,
array(
'id'=>array('label'=>'ID','url'=>URL::link('user','invoice/view/')),
'date_orig'=>array('label'=>'Date Issued'),
'due_date'=>array('label'=>'Date Due'),
'total(TRUE)'=>array('label'=>'Total','class'=>'right'),
'total_credits(TRUE)'=>array('label'=>'Credits','class'=>'right'),
'payments_total(TRUE)'=>array('label'=>'Payments','class'=>'right'),
'due(TRUE)'=>array('label'=>'Still Due','class'=>'right'),
),
array(
'page'=>TRUE,
'type'=>'select',
'form'=>URL::link('user','invoice/view'),
)),
));
}
/**
* View an Invoice
*/
public function action_view() {
list($id,$output) = Table::page(__METHOD__);
$io = ORM::factory('Invoice',$id);
if (! $io->loaded() OR ! Auth::instance()->authorised($io->account)) {
$this->template->content = 'Unauthorised or doesnt exist?';
return FALSE;
}
$output .= View::factory($this->viewpath())
->set('mediapath',Route::get('default/media'))
->set('io',$io);
if ($io->due() AND ! $io->cart_exists()) {
$output .= View::factory($this->viewpath().'/pay')
->set('mid',$io->mid())
->set('o',$io);
}
if (! $io->status) {
// Add a gribber popup
// @todo Make a gribber popup a class on its own.
Style::add(array(
'type'=>'file',
'data'=>'css/jquery.gritter.css',
'media'=>'screen',
));
Script::add(array(
'type'=>'file',
'data'=>'js/jquery.gritter-1.5.js',
));
Script::add(array(
'type'=>'stdin',
'data'=>sprintf(
'$(document).ready(function() {
$.extend($.gritter.options, {
fade_in_speed: "medium",
fade_out_speed: 2000,
time: "3000",
sticky: false,
});
$.gritter.add({
title: "%s",
text: "%s",
image: "%s",
});});',
'Cancelled','Invoice CANCELLED',URL::site().SystemMessage::image('info',true)
)
));
Style::add(array(
'type'=>'stdin',
'data'=>'
#watermark {
color: #800000;
font-size: 4em;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
position: absolute;
width: 100%;
height: 100%;
margin: 0;
z-index: 1;
left:250px;
top:-20px;
}
'));
$output .= '<div id="watermark"><p>Invoice CANCELLED.</p></div>';
}
Block::add(array(
'title'=>sprintf('%s: %s - %s',_('Invoice'),$io->refnum(),$io->account->name()),
'body'=>$output,
));
}
/**
* Download an invoice
*/
public function action_download() {
$io = ORM::factory('Invoice',$this->request->param('id'));
$this->response->body(Invoice::instance($io)->pdf()->Output(sprintf('%s.pdf',$io->refnum()),'D'));
$this->response->headers(array('Content-Type' => 'application/pdf'));
$this->auto_render = FALSE;
}
} }
?> ?>

View File

@ -10,5 +10,80 @@
* @license http://dev.osbill.net/license.html * @license http://dev.osbill.net/license.html
*/ */
class Controller_User_Invoice extends Controller_Invoice { class Controller_User_Invoice extends Controller_Invoice {
protected $secure_actions = array(
'download'=>TRUE,
'list'=>TRUE,
'view'=>TRUE,
);
/**
* Download an invoice
*/
public function action_download() {
$io = ORM::factory('Invoice',$this->request->param('id'));
$this->response->body(Invoice::instance($io)->pdf()->Output(sprintf('%s.pdf',$io->refnum()),'D'));
$this->response->headers(array('Content-Type' => 'application/pdf'));
$this->auto_render = FALSE;
}
/**
* Show a list of invoices
*/
public function action_list() {
Block::factory()
->title(sprintf('Invoices for Account: %s',$this->ao->accnum()))
->title_icon('icon-th-list')
->body(Table::factory()
->jssort('invoices')
->data($this->ao->invoice->find_all())
->columns(array(
'id'=>'ID',
'date_orig'=>'Date Issued',
'due_date'=>'Date Due',
'total(TRUE)'=>'Total',
'total_credits(TRUE)'=>'Credits',
'payments_total(TRUE)'=>'Payments',
'due(TRUE)'=>'Still Due',
))
->prepend(array(
'id'=>array('url'=>URL::link('user','invoice/view/')),
))
);
}
/**
* View an Invoice
*/
public function action_view() {
list($id,$output) = Table::page(__METHOD__);
$io = ORM::factory('Invoice',$id);
if (! $io->loaded() OR ! Auth::instance()->authorised($io->account))
throw HTTP_Exception::factory(403,'Service either doesnt exist, or you are not authorised to see it');
$output .= View::factory('invoice/user/view')
->set('mediapath',Route::get('default/media'))
->set('o',$io);
if ($io->due() AND ! $io->cart_exists())
$output .= View::factory('/invoice/user/view/pay')
->set('mid',$io->mid())
->set('o',$io);
if (! $io->status) {
Style::factory()
->type('file')
->data('media/css/pages/invoice.css');
$output .= '<div id="watermark">Invoice CANCELLED.</div>';
}
Block::factory()
->title(sprintf('%s: %s - %s',_('Invoice'),$io->refnum(),$io->account->name()))
->title_icon('icon-list-alt')
->body($output);
}
} }
?> ?>

View File

@ -0,0 +1,13 @@
#watermark {
color: #800000;
font-size: 4em;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
position: absolute;
width: 100%;
height: 100%;
margin: 0;
z-index: 1;
left:350px;
top:-50px;
}

View File

@ -1,84 +1,75 @@
<!-- @todo NEED to translate this --> <div class="row">
<table class="box-left" border="0"> <div class="span11">
<tr> <div class="span5">
<td style="vertical-align: top"> <div class="row">
<table class="company_details" border="0"> <table>
<tr>
<td class="logo"><?php echo Company::instance()->logo(); ?></td>
<td class="address">
<span class="company_name"><?php echo Company::instance()->name(); ?></span><br/>
<?php echo Company::instance()->taxid(); ?><br/>
<br/>
<?php echo Company::instance()->address(); ?><br/>
<br/>
<?php echo Company::instance()->contacts(); ?>
</td>
</tr>
</table>
</td>
<td>&nbsp;</td>
<td>
<table class="invoice_summary" border="0">
<tr>
<td>TAX INVOICE</td>
<td class="bold-right"><?php echo $io->id(); ?></td>
</tr>
<tr>
<td>Issue Date</td>
<td class="bold-right"><?php echo $io->display('date_orig'); ?></td>
</tr>
<tr>
<td>Due Date</td>
<td class="bold-right"><?php echo $io->display('due_date'); ?></td>
</tr>
<tr>
<td>Current Charges</td>
<td class="bold-right"><?php echo $io->total_charges(TRUE); ?></td>
</tr>
<tr>
<td>Payments Received to Date</td>
<td class="bold-right"><?php echo $io->payments_total(TRUE); ?></td>
</tr>
<tr>
<td>Credits Applied to Date</td>
<td class="bold-right"><?php echo $io->total_credits(TRUE); ?></td>
</tr>
<tr>
<td>Total Charges Due This Invoice</td>
<td class="bold-right"><?php echo $io->due(TRUE); ?></td>
</tr>
</table>
</td>
</tr>
<tr><td class="spacer" colspan="3">&nbsp;</td></tr>
<tr>
<td colspan="3">
<table border="0">
<tr>
<td class="head" colspan="4">Charges Detail:</td>
</tr>
<?php foreach ($io->items_index('period') as $rs => $items) { ?>
<tr> <tr>
<td><div id="toggle_<?php echo $rs; ?>"><?php echo HTML::image($mediapath->uri(array('file'=>'img/toggle-closed.png')),array('alt'=>'+')); ?></div><script type="text/javascript">$("#toggle_<?php echo $rs; ?>").click(function() {$('#detail_toggle_<?php echo $rs; ?>').toggle();});</script></td> <td style="vertical-align: top"><?php echo HTML::image('http://www.gth.bgo.co/logo-blue'); ?></td>
<?php if ($rs) { ?> <td style="text-align: right; font-weight: bold">
<td><?php echo StaticList_RecurSchedule::get($rs); ?></td> <?php echo Company::instance()->name(); ?><br/>
<td><?php printf('%s Service(s)',count($items)); ?></td> <?php echo Company::instance()->taxid(); ?><br/>
<td>&nbsp;</td> <br/>
<?php } else { ?> <?php echo Company::instance()->address(); ?><br/>
<td colspan="3">Other Items</td> <br/>
<?php } ?> <?php echo Company::instance()->contacts(); ?>
</td>
</tr> </tr>
<tr> </table>
<td>&nbsp;</td> </div> <!-- /row -->
<td colspan="2"> </div> <!-- /span -->
<div id="detail_toggle_<?php echo $rs; ?>">
<table class="box-full" border="0"> <div class="span5">
<?php if ($items) { <div class="row">
foreach ($items as $k=>$service_id) { <div class="dl-horizontal">
$i = 0; <dt>Tax Invoice</dt>
$lp = NULL; <dd><?php echo $o->id(); ?></dd>
$ito_tax = NULL; <dt>Issue Date</dt>
foreach ($io->items_service($service_id) as $ito) { <dd><?php echo $o->display('date_orig'); ?></dd>
<dt>Due Date</dt>
<dd><?php echo $o->display('due_date'); ?></dd>
<dt>Current Charges</dt>
<dd><?php echo $o->total_charges(TRUE); ?></dd>
<dt>Payments Recieved</dt>
<dd><?php echo $o->payments_total(TRUE); ?></dd>
<dt>Credits Applied</dt>
<dd><?php echo $o->total_credits(TRUE); ?></dd>
<dt>Still Due</dt>
<dd><?php echo $o->due(TRUE); ?></dd>
</div>
</div> <!-- /row -->
</div> <!-- /span -->
</div> <!-- /span -->
</div>
<div class="row">
<div class="span11">
<h4>Charge Details</h4>
<div class="accordion" id="charges">
<div class="accordion-group">
<?php foreach ($o->items_index('period') as $rs => $items) : ?>
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#charges" data-target="#collapse_<?php echo $rs; ?>">
<?php if ($rs) :
printf('%s - %s service(s)',StaticList_RecurSchedule::get($rs),count($items));
else :
echo 'Other Items';
endif ?>
</a>
</div>
<?php if ($items) : ?>
<div id="collapse_<?php echo $rs; ?>" class="accordion-body collapse in">
<table>
<?php
foreach ($items as $k=>$service_id) :
$i = 0;
$lp = NULL;
$ito_tax = NULL;
foreach ($o->items_service($service_id) as $ito) {
$ito_tax = $ito; $ito_tax = $ito;
// Our first line we show the Service Details // Our first line we show the Service Details
if ($ito->item_type == 0 AND $ito->product_id != $lp) { if ($ito->item_type == 0 AND $ito->product_id != $lp) {
@ -87,7 +78,7 @@
<tr class="head"> <tr class="head">
<td><?php echo HTML::anchor(URL::link('user','service/view/'.$ito->service_id),$ito->service->id()); ?></td> <td><?php echo HTML::anchor(URL::link('user','service/view/'.$ito->service_id),$ito->service->id()); ?></td>
<td colspan="5"><?php printf('%s - %s',$ito->product->title(),$ito->service->name()); ?> (<?php echo $ito->product_id; ?>)</td> <td colspan="5"><?php printf('%s - %s',$ito->product->title(),$ito->service->name()); ?> (<?php echo $ito->product_id; ?>)</td>
<td class="right"><?php echo ($i++==0 ? Currency::display($io->items_service_total($ito->service_id)) : '&nbsp;');?></td> <td class="right"><?php echo ($i++==0 ? Currency::display($o->items_service_total($ito->service_id)) : '&nbsp;');?></td>
</tr> </tr>
<!-- END Product Information --> <!-- END Product Information -->
<?php } ?> <?php } ?>
@ -106,40 +97,37 @@
<tr> <tr>
<td colspan="4">&nbsp;</td> <td colspan="4">&nbsp;</td>
<td><?php echo _('Discounts'); ?></td> <td><?php echo _('Discounts'); ?></td>
<td class="right">(<?php echo Currency::display($io->items_service_discount($ito->service_id));?>)</td> <td class="right">(<?php echo Currency::display($o->items_service_discount($ito->service_id));?>)</td>
</tr> </tr>
<?php } ?> <?php } ?>
<!-- END Service Discount Information --> <!-- END Service Discount Information -->
<?php } ?> <?php } ?>
<?php if ($ito_tax) { ?>
<?php if ($ito_tax) { ?>
<!-- Product Sub Items Tax --> <!-- Product Sub Items Tax -->
<tr> <tr>
<td colspan="4">&nbsp;</td> <td colspan="4">&nbsp;</td>
<td><?php echo _('Taxes'); ?></td> <td><?php echo _('Taxes'); ?></td>
<td class="right"><?php echo Currency::display($io->items_service_tax($ito->service_id));?>&nbsp;</td> <td class="right"><?php echo Currency::display($o->items_service_tax($ito->service_id));?>&nbsp;</td>
</tr> </tr>
<!-- END Product Sub Items Tax --> <!-- END Product Sub Items Tax -->
<?php } ?>
<?php } ?> <?php } ?>
<?php } ?> <?php endforeach ?>
</table> <?php endif ?>
</div>
</td> </table>
<td>&nbsp;</td> </div>
</tr> <?php endforeach ?>
<?php } ?>
<?php if ($io->items_index('account')) { ?> <?php if ($o->items_index('account')) : ?>
<tr> <div class="accordion-heading">
<td><?php echo HTML::image($mediapath->uri(array('file'=>'img/toggle-closed.png')),array('alt'=>'+')); ?></td> <a class="accordion-toggle" data-toggle="collapse" data-parent="#charges" data-target="#collapse_other">Other Items</a>
<td colspan="2">Other Invoice Items</td> </div>
<td>&nbsp;</td>
</tr> <div id="collapse_<?php echo $rs; ?>" class="accordion-body collapse">
<tr> <table>
<td>&nbsp;</td>
<td colspan="2"> <?php foreach ($o->items_index('account') as $id => $ito) : ?>
<div id="detail_toggle_other">
<table class="box-full" border="0">
<?php foreach ($io->items_index('account') as $id => $ito) { ?>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td><?php echo $ito->trannum();?></td> <td><?php echo $ito->trannum();?></td>
@ -152,67 +140,69 @@
<tr> <tr>
<td colspan="4">&nbsp;</td> <td colspan="4">&nbsp;</td>
<td><?php echo _('Taxes'); ?></td> <td><?php echo _('Taxes'); ?></td>
<td class="right"><?php echo Currency::display($io->items_service_tax($ito->service_id));?>&nbsp;</td> <td class="right"><?php echo Currency::display($o->items_service_tax($ito->service_id));?>&nbsp;</td>
</tr> </tr>
<!-- Product End Sub Items Tax --> <!-- Product End Sub Items Tax -->
<?php } ?> <?php endforeach ?>
</table>
</div> </table>
</td> </div>
<td>&nbsp;</td> <?php endif ?>
</tr>
<?php } ?> </div>
<!-- Invoice Sub Total --> </div>
<tr>
<td class="head" colspan="2">Sub Total of Items:</td> </div> <!-- /span -->
<td class="bold-right" colspan="2"><?php echo $io->subtotal(TRUE); ?></td> </div>
</tr>
<!-- END Invoice Sub Total --> <div class="row">
<?php if ($io->total_credits()) { ?> <div class="span11">
<!-- Invoice Credits --> <div class="span5">
<tr> </div> <!-- /span -->
<td class="head" colspan="2">Credits Received:</td>
<td class="bold-right" colspan="2"><?php echo $io->total_credits(TRUE); ?></td> <div class="span5">
</tr> <div class="row">
<!-- END Invoice Credits --> <div class="dl-horizontal">
<?php } ?> <!-- Sub Total -->
<?php if ($io->total_discounts()) { ?> <dt>Sub Total</dt>
<!-- Invoice Discounts Total --> <dd><?php echo $o->subtotal(TRUE); ?></dd>
<tr> <!-- END Invoice Sub Total -->
<td class="head" colspan="2">Discounts:</td>
<td class="bold-right" colspan="2">(<?php echo $io->total_discounts(TRUE); ?>)</td> <!-- Invoice Credits -->
</tr> <?php if ($o->total_credits()) : ?>
<!-- END Invoice Discounts Total --> <dt>Credits</dt>
<?php } ?> <dd><?php echo $o->total_credits(TRUE); ?></dd>
<!-- Invoice Taxes Total --> <?php endif ?>
<tr> <!-- END Invoice Credits -->
<td class="head" colspan="4">Taxes Included:</td>
</tr> <!-- Invoice Discounts Total -->
<?php foreach ($io->tax_summary() as $tid => $amount) { <?php if ($o->total_discounts()) : ?>
$m = ORM::factory('Tax',$tid); ?> <dt>Discounts</dt>
<tr> <dd><?php echo $o->total_discounts(TRUE); ?></dd>
<td>&nbsp;</td> <?php endif ?>
<td><?php echo $m->description; ?></td> <!-- END Invoice Discounts Total -->
<td class="bold-right" colspan="2"><?php echo Currency::display($amount); ?></td>
</tr> <!-- Invoice Taxes Total -->
<?php }?> <dt>Taxes Included:</dt>
<!-- END Invoice Taxes Total --> <?php foreach ($o->tax_summary() as $tid => $amount) :
<!-- Invoice Total --> $m = ORM::factory('Tax',$tid); ?>
<tr> <dd><?php printf('%s (%s)',Currency::display($amount),$m->description); ?><dd>
<td class="head" colspan="2">Total This Invoice:</td> <?php endforeach ?>
<td class="bold-right" colspan="2"><?php echo $io->total(TRUE); ?></td> <!-- END Invoice Taxes Total -->
</tr>
<!-- END Invoice Total --> <!-- Invoice Total -->
<!-- Account Total Due --> <dt>Total This Invoice:</dt>
<tr> <dd><?php echo $o->total(TRUE); ?></dd>
<td class="head" colspan="2">Total Outstanding This Account:</td> <!-- END Invoice Total -->
<td class="bold-right" colspan="2"><?php echo $io->account->invoices_due_total(NULL,TRUE); ?></td> <!-- Account Total Due -->
</tr> <dt>Total Outstanding This Account:</dt>
<!-- END Account Total Due --> <dd><?php echo $o->account->invoices_due_total(NULL,TRUE); ?></dd>
</table> <!-- END Account Total Due -->
</td>
</tr> </div>
<tr> </div> <!-- /row -->
<td><?php echo HTML::anchor(URL::link('user','invoice/download/'.$io->id),'Download detailed invoice'); ?></td> </div> <!-- /span -->
</tr> </div> <!-- /span -->
</table> </div>
<?php echo Form::button(URL::link('user','invoice/download/'.$o->id),'Download detailed invoice',array('class'=>'btn btn-primary pull-right')); ?></td>

View File

@ -2,38 +2,38 @@
<fieldset class="span5"> <fieldset class="span5">
<legend>Service Information</legend> <legend>Service Information</legend>
<div class="dl-horizontal"> <div class="dl-horizontal">
<dt>Account</dt> <dt>Account</dt>
<dd><?php printf('%s (%s)',$o->account->name(),$o->account->accnum()); ?></dd> <dd><?php printf('%s (%s)',$o->account->name(),$o->account->accnum()); ?></dd>
<dt>Service Active</dt> <dt>Service Active</dt>
<dd><?php echo $o->label_bool('status',TRUE); ?></dd> <dd><?php echo $o->label_bool('status',TRUE); ?></dd>
<dt>Billing Period</dt> <dt>Billing Period</dt>
<dd><?php echo $o->display('recur_schedule');?></dd> <dd><?php echo $o->display('recur_schedule');?></dd>
<dt>Cost</dt> <dt>Cost</dt>
<dd><?php echo $o->price(TRUE,TRUE); if ($o->pending_change()) echo ' *'; ?></dd> <dd><?php echo $o->price(TRUE,TRUE); if ($o->pending_change()) echo ' *'; ?></dd>
<?php if (is_null($o->price) OR ($o->price<=$o->product->price($o->price_group,$o->recur_schedule,'price_base'))) : ?> <?php if (is_null($o->price) OR ($o->price<=$o->product->price($o->price_group,$o->recur_schedule,'price_base'))) : ?>
<dt>Service</dt> <dt>Service</dt>
<dd><?php echo HTML::anchor('product/view/'.$o->product_id,$o->product->title()); ?></dd> <dd><?php echo HTML::anchor('product/view/'.$o->product_id,$o->product->title()); ?></dd>
<?php endif ?> <?php endif ?>
<dt>Invoiced To</dt> <dt>Invoiced To</dt>
<dd><?php echo $o->invoiced_to(TRUE); ?></dd> <dd><?php echo $o->invoiced_to(TRUE); ?></dd>
<dt>Paid To</dt> <dt>Paid To</dt>
<dd><?php echo $o->paid_to(TRUE); ?></dd> <dd><?php echo $o->paid_to(TRUE); ?></dd>
<dt>Date Next Invoice</dt> <dt>Date Next Invoice</dt>
<dd><?php echo $o->display('date_next_invoice'); ?></dd> <dd><?php echo $o->display('date_next_invoice'); ?></dd>
<dt>Current Invoices Due</dt> <dt>Current Invoices Due</dt>
<dd><?php echo $o->due(TRUE); ?></dd> <dd><?php echo $o->due(TRUE); ?></dd>
</div> <!-- /dl-horizontal --> </div> <!-- /dl-horizontal -->
</fieldset> </fieldset>
<?php if ($o->product->feature_summary()) : <?php if ($o->product->feature_summary()) :