Work on HTML invoice and internal logic
This commit is contained in:
parent
a464d73f9a
commit
f0c1f8800e
@ -50,6 +50,10 @@ class Company {
|
|||||||
return Config::instance()->so->site_details('fax');
|
return Config::instance()->so->site_details('fax');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function email() {
|
||||||
|
return Config::instance()->so->site_details('email');
|
||||||
|
}
|
||||||
|
|
||||||
public static function contacts() {
|
public static function contacts() {
|
||||||
return 'Tel: '.static::phone();
|
return 'Tel: '.static::phone();
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,12 @@
|
|||||||
class Currency {
|
class Currency {
|
||||||
public static function display($amount) {
|
public static function display($amount) {
|
||||||
// @todo $cid and therefore precision should come from a global session value.
|
// @todo $cid and therefore precision should come from a global session value.
|
||||||
|
return Num::format(Currency::round($amount),2,TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function round($amount) {
|
||||||
// @todo This rounding needs to be system configurable.
|
// @todo This rounding needs to be system configurable.
|
||||||
return Num::format(round($amount,2),2,TRUE);
|
return Num::round($amount,2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -69,7 +69,7 @@ class lnApp_SystemMessage extends HTMLRender {
|
|||||||
/**
|
/**
|
||||||
* Render an image for the System Message
|
* Render an image for the System Message
|
||||||
*/
|
*/
|
||||||
private static function image($type,$raw=false,$big=false,$alt='') {
|
public static function image($type,$raw=false,$big=false,$alt='') {
|
||||||
$mediapath = Route::get(static::$_media_path);
|
$mediapath = Route::get(static::$_media_path);
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
|
@ -129,7 +129,7 @@ abstract class ORMOSB extends ORM {
|
|||||||
if ($this->_changed)
|
if ($this->_changed)
|
||||||
foreach ($this->_changed as $c)
|
foreach ($this->_changed as $c)
|
||||||
if ($this->_table_columns[$c]['data_type'] == 'blob') {
|
if ($this->_table_columns[$c]['data_type'] == 'blob') {
|
||||||
$this->$c = $this->blob($this->$c,TRUE);
|
$this->_object[$c] = $this->blob($this->_object[$c],TRUE);
|
||||||
|
|
||||||
// We need to reset our auto_convert flag
|
// We need to reset our auto_convert flag
|
||||||
if (isset($this->_table_columns[$c]['auto_convert']))
|
if (isset($this->_table_columns[$c]['auto_convert']))
|
||||||
|
@ -53,6 +53,7 @@ class Controller_User_Invoice extends Controller_TemplateDefault_User {
|
|||||||
|
|
||||||
if (! $io->loaded() OR (! Auth::instance()->authorised($io->account_id,$io->affiliate_id) AND ! in_array($this->ao->affiliate->id,$io->service_affiliates()))) {
|
if (! $io->loaded() OR (! Auth::instance()->authorised($io->account_id,$io->affiliate_id) AND ! in_array($this->ao->affiliate->id,$io->service_affiliates()))) {
|
||||||
$this->template->content = 'Unauthorised or doesnt exist?';
|
$this->template->content = 'Unauthorised or doesnt exist?';
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +61,58 @@ class Controller_User_Invoice extends Controller_TemplateDefault_User {
|
|||||||
->set('mediapath',Route::get('default/media'))
|
->set('mediapath',Route::get('default/media'))
|
||||||
->set('io',$io);
|
->set('io',$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:350px;
|
||||||
|
top:-200px;
|
||||||
|
}
|
||||||
|
'));
|
||||||
|
|
||||||
|
$output .= '<div id="watermark"><p>Invoice CANCELLED.</p></div>';
|
||||||
|
}
|
||||||
|
|
||||||
Block::add(array(
|
Block::add(array(
|
||||||
'title'=>sprintf('%s: %s - %s',_('Invoice'),$io->refnum(),$io->account->name()),
|
'title'=>sprintf('%s: %s - %s',_('Invoice'),$io->refnum(),$io->account->name()),
|
||||||
'body'=>$output,
|
'body'=>$output,
|
||||||
|
@ -49,6 +49,33 @@ class Model_Invoice extends ORMOSB {
|
|||||||
|
|
||||||
// Items belonging to an invoice
|
// Items belonging to an invoice
|
||||||
private $invoice_items = array();
|
private $invoice_items = array();
|
||||||
|
private $subitems_load = FALSE;
|
||||||
|
|
||||||
|
public function __construct($id = NULL) {
|
||||||
|
// Load our model.
|
||||||
|
parent::__construct($id);
|
||||||
|
|
||||||
|
return $this->load_sub_items();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function load_sub_items() {
|
||||||
|
// Load our sub items
|
||||||
|
if (! $this->subitems_load AND $this->loaded()) {
|
||||||
|
$this->invoice_items = $this->invoice_item->find_all()->as_array();
|
||||||
|
$this->subitems_load = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of invoice items for this payment.
|
||||||
|
*/
|
||||||
|
public function items() {
|
||||||
|
$this->load_sub_items();
|
||||||
|
|
||||||
|
return $this->invoice_items;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the Invoice Number
|
* Display the Invoice Number
|
||||||
@ -69,20 +96,13 @@ class Model_Invoice extends ORMOSB {
|
|||||||
*/
|
*/
|
||||||
public function due($format=FALSE) {
|
public function due($format=FALSE) {
|
||||||
// If the invoice is active calculate the due amount
|
// If the invoice is active calculate the due amount
|
||||||
$result = $this->status ? round($this->total()-$this->payments_total(),2) : 0;
|
$result = $this->status ? $this->total()-$this->payments_total() : 0;
|
||||||
|
|
||||||
return $format ? Currency::display($result) : $result;
|
// @todo This should not be required.
|
||||||
}
|
if ((Currency::round($result) == .01) or Currency::round($result) == .02)
|
||||||
|
$result = 0;
|
||||||
|
|
||||||
/**
|
return $format ? Currency::display($result) : Currency::round($result);
|
||||||
* Return a list of invoice items for this invoice.
|
|
||||||
*/
|
|
||||||
public function items() {
|
|
||||||
// If we havent been changed, we'll load the records from the DB.
|
|
||||||
if ($this->loaded() AND ! $this->_changed)
|
|
||||||
return $this->invoice_item->order_by('service_id,item_type,module_id')->find_all()->as_array();
|
|
||||||
else
|
|
||||||
return $this->invoice_items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,31 +111,28 @@ class Model_Invoice extends ORMOSB {
|
|||||||
public function subtotal($format=FALSE) {
|
public function subtotal($format=FALSE) {
|
||||||
$result = 0;
|
$result = 0;
|
||||||
|
|
||||||
// @todo This rounding should be a system config.
|
|
||||||
foreach ($this->items() as $ito)
|
foreach ($this->items() as $ito)
|
||||||
$result += round($ito->subtotal(),2);
|
$result += $ito->subtotal();
|
||||||
|
|
||||||
return $format ? Currency::display($result) : $result;
|
return $format ? Currency::display($result) : Currency::round($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function discount($format=FALSE) {
|
public function discount($format=FALSE) {
|
||||||
$result = 0;
|
$result = 0;
|
||||||
|
|
||||||
// @todo This rounding should be a system config.
|
|
||||||
foreach ($this->items() as $ito)
|
foreach ($this->items() as $ito)
|
||||||
$result += round($ito->discount_amt,2);
|
$result += $ito->discount_amt;
|
||||||
|
|
||||||
return $format ? Currency::display($result) : $result;
|
return $format ? Currency::display($result) : Currency::round($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tax($format=FALSE) {
|
public function tax($format=FALSE) {
|
||||||
$result = 0;
|
$result = 0;
|
||||||
|
|
||||||
// @todo This rounding should be a system config.
|
|
||||||
foreach ($this->items() as $ito)
|
foreach ($this->items() as $ito)
|
||||||
$result += round($ito->tax(),2);
|
$result += $ito->tax();
|
||||||
|
|
||||||
return $format ? Currency::display($result) : $result;
|
return $format ? Currency::display($result) : Currency::round($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,18 +141,17 @@ class Model_Invoice extends ORMOSB {
|
|||||||
public function total($format=FALSE) {
|
public function total($format=FALSE) {
|
||||||
$result = 0;
|
$result = 0;
|
||||||
|
|
||||||
// @todo This rounding should be a system config.
|
|
||||||
foreach ($this->items() as $ito)
|
foreach ($this->items() as $ito)
|
||||||
$result += round($ito->total(),2);
|
$result += $ito->total();
|
||||||
|
|
||||||
// Reduce by any credits
|
// Reduce by any credits
|
||||||
$result -= round($this->credit_amt,2);
|
$result -= $this->credit_amt;
|
||||||
|
|
||||||
return $format ? Currency::display($result) : $result;
|
return $format ? Currency::display($result) : Currency::round($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function payments() {
|
public function payments() {
|
||||||
return ($this->loaded() AND ! $this->_changed) ? $this->payment_item->find_all() : array();
|
return $this->payment_item->find_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function payments_total($format=FALSE) {
|
public function payments_total($format=FALSE) {
|
||||||
@ -144,7 +160,44 @@ class Model_Invoice extends ORMOSB {
|
|||||||
foreach ($this->payments() as $po)
|
foreach ($this->payments() as $po)
|
||||||
$result += $po->alloc_amt;
|
$result += $po->alloc_amt;
|
||||||
|
|
||||||
return $format ? Currency::display($result) : $result;
|
return $format ? Currency::display($result) : Currency::round($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide a sorted list of items by an index
|
||||||
|
*/
|
||||||
|
public function items_index($index) {
|
||||||
|
static $result = array();
|
||||||
|
|
||||||
|
// We'll return a cached result for quicker processing
|
||||||
|
if (! $this->_changed AND array_key_exists($index,$result))
|
||||||
|
return $result[$index];
|
||||||
|
|
||||||
|
foreach ($this->items() as $ito) {
|
||||||
|
switch ($index) {
|
||||||
|
case 'account':
|
||||||
|
if (! $ito->service_id)
|
||||||
|
$result[$index][$ito->id] = $ito;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'period':
|
||||||
|
// We only show the services in this period
|
||||||
|
if (! is_null($ito->recurring_schedule) AND (empty($result[$index][$ito->recurring_schedule]) OR ! in_array($ito->service_id,$result[$index][$ito->recurring_schedule])))
|
||||||
|
$result[$index][$ito->recurring_schedule][] = $ito->service_id;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'service':
|
||||||
|
default:
|
||||||
|
if ($ito->service_id)
|
||||||
|
$result[$index][$ito->service_id][] = $ito;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_key_exists($index,$result) ? $result[$index] : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,6 +205,7 @@ class Model_Invoice extends ORMOSB {
|
|||||||
*
|
*
|
||||||
* We use this to list details by service on an invoice.
|
* We use this to list details by service on an invoice.
|
||||||
*/
|
*/
|
||||||
|
// @todo to retire
|
||||||
public function items_services(array $items=array()) {
|
public function items_services(array $items=array()) {
|
||||||
$result = array();
|
$result = array();
|
||||||
if (! $items)
|
if (! $items)
|
||||||
@ -164,21 +218,33 @@ class Model_Invoice extends ORMOSB {
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// @todo to retire
|
||||||
* Return all invoice items for a service optionally by recurring schedule
|
public function items_invoice() {
|
||||||
*/
|
|
||||||
public function items_service($sid,$rs=NULL) {
|
|
||||||
$result = array();
|
$result = array();
|
||||||
$items = $this->items();
|
$items = $this->items();
|
||||||
|
|
||||||
Sort::MAsort($items,'item_type');
|
|
||||||
foreach ($items as $ito)
|
foreach ($items as $ito)
|
||||||
if ($ito->service_id == $sid AND (is_null($rs) OR $ito->recurring_schedule == $rs))
|
if (! $ito->service_id AND empty($result[$ito->id]))
|
||||||
array_push($result,$ito);
|
$result[$ito->id] = $ito;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all invoice items for a specific service
|
||||||
|
*/
|
||||||
|
public function items_service($service_id) {
|
||||||
|
$svs = $this->items_index('service');
|
||||||
|
|
||||||
|
if (array_key_exists($service_id,$svs)) {
|
||||||
|
Sort::MAsort($svs[$service_id],'item_type');
|
||||||
|
|
||||||
|
return $svs[$service_id];
|
||||||
|
} else
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo to retire
|
||||||
/**
|
/**
|
||||||
* Return a list of periods and services
|
* Return a list of periods and services
|
||||||
*
|
*
|
||||||
@ -207,6 +273,7 @@ class Model_Invoice extends ORMOSB {
|
|||||||
*
|
*
|
||||||
* We summaries based on product.
|
* We summaries based on product.
|
||||||
*/
|
*/
|
||||||
|
// @todo
|
||||||
public function items_summary() {
|
public function items_summary() {
|
||||||
$result = array();
|
$result = array();
|
||||||
|
|
||||||
@ -303,6 +370,7 @@ class Model_Invoice extends ORMOSB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function min_due($date) {
|
public function min_due($date) {
|
||||||
|
// @todo This should be a DB confirm item
|
||||||
return ($date < time()) ? time()+Kohana::config('config.invoice.min_due_days')*86400 : $date;
|
return ($date < time()) ? time()+Kohana::config('config.invoice.min_due_days')*86400 : $date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,41 +63,83 @@ class Model_Invoice_Item extends ORMOSB {
|
|||||||
if (! $result)
|
if (! $result)
|
||||||
$result += round($this->subtotal() *.1,2);
|
$result += round($this->subtotal() *.1,2);
|
||||||
|
|
||||||
return $result;
|
return Currency::round($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This total of this item before discounts and taxes
|
// This total of this item before discounts and taxes
|
||||||
public function subtotal() {
|
public function subtotal() {
|
||||||
return $this->price_base*$this->quantity;
|
return Currency::round($this->price_base*$this->quantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The total of all discounts
|
// The total of all discounts
|
||||||
public function discount() {
|
public function discount() {
|
||||||
return $this->discount_amt;
|
return Currency::round($this->discount_amt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function total() {
|
public function total() {
|
||||||
// @todo This rounding should be a system config
|
return Currency::round($this->subtotal()+$this->tax()-$this->discount());
|
||||||
return round($this->subtotal()+$this->tax()-$this->discount(),2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name for an invoice item
|
||||||
|
*/
|
||||||
public function name() {
|
public function name() {
|
||||||
return $this->product_name ? $this->product_name : ($this->item_type == 0 ? _('Service') : _('Other'));
|
switch ($this->item_type) {
|
||||||
|
case 0: return _('Service');
|
||||||
|
|
||||||
|
case 1: return _('Item');
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 126:
|
||||||
|
case 127: return _('Charge');
|
||||||
|
|
||||||
|
case 5: return $this->charge->description;
|
||||||
|
|
||||||
|
default: return _('Other');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detail behind an invoice item
|
||||||
|
*/
|
||||||
public function detail() {
|
public function detail() {
|
||||||
return ($this->item_type == 0 OR $this->quantity == 1) ? HTML::nbsp('') : sprintf('%s@%3.2f',$this->quantity,$this->price_base);
|
switch ($this->item_type) {
|
||||||
|
case 0: return '';
|
||||||
|
|
||||||
|
case 1: return _('Hardware');
|
||||||
|
|
||||||
|
case 2: return _('Service Relocation Fee');
|
||||||
|
|
||||||
|
case 3: return _('Service Change Fee');
|
||||||
|
|
||||||
|
case 4: return _('Service Connection Fee');
|
||||||
|
|
||||||
|
case 5: return sprintf('%s@%3.2f',$this->quantity,$this->price_base);
|
||||||
|
|
||||||
|
case 6: return _('Service Excess Fee');
|
||||||
|
|
||||||
|
case 126: return _('Rounding');
|
||||||
|
|
||||||
|
case 127: return _('Late Payment Fee');
|
||||||
|
|
||||||
|
default: '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function invoice_detail_items() {
|
public function invoice_detail_items() {
|
||||||
// @todo To fix up this function - needs to be better formed.
|
switch ($this->item_type) {
|
||||||
if ($this->item_type == 5)
|
case 0:
|
||||||
return $this->charge->details('invoice_detail_items');
|
|
||||||
|
|
||||||
if ($this->item_type != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
return $this->service->details('invoice_detail_items');
|
return $this->service->details('invoice_detail_items');
|
||||||
|
case 4:
|
||||||
|
return array('Charge'=>_('Service Connection Fee'));
|
||||||
|
case 5:
|
||||||
|
return $this->charge->details('invoice_detail_items');
|
||||||
|
default:
|
||||||
|
return array('Item'=>$this->item_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(Validation $validation = NULL) {
|
public function save(Validation $validation = NULL) {
|
||||||
@ -107,6 +149,7 @@ class Model_Invoice_Item extends ORMOSB {
|
|||||||
// Need to save the taxes and discounts associated with the invoice_item
|
// Need to save the taxes and discounts associated with the invoice_item
|
||||||
// @todo This needs to only check if the records have previously been saved, and update them.
|
// @todo This needs to only check if the records have previously been saved, and update them.
|
||||||
if ($this->saved()) {
|
if ($this->saved()) {
|
||||||
|
//@todo When updating a record, we shouldnt create a new tax item.
|
||||||
$iito = ORM::factory('invoice_item_tax');
|
$iito = ORM::factory('invoice_item_tax');
|
||||||
|
|
||||||
// Save TAX details
|
// Save TAX details
|
||||||
|
@ -5,7 +5,14 @@
|
|||||||
<table class="company_details" border="0">
|
<table class="company_details" border="0">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="logo"><?php echo Config::logo(); ?></td>
|
<td class="logo"><?php echo Config::logo(); ?></td>
|
||||||
<td class="address"><span class="company_name"><?php echo Company::name(); ?></span><br/><?php echo Company::address(); ?><br/><?php echo Company::contacts(); ?></td>
|
<td class="address">
|
||||||
|
<span class="company_name"><?php echo Company::name(); ?></span><br/>
|
||||||
|
<?php echo Company::taxid(); ?><br/>
|
||||||
|
<br/>
|
||||||
|
<?php echo Company::address(); ?><br/>
|
||||||
|
<br/>
|
||||||
|
<?php echo Company::contacts(); ?>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
@ -42,37 +49,44 @@
|
|||||||
<tr><td class="spacer" colspan="3"> </td></tr>
|
<tr><td class="spacer" colspan="3"> </td></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3">
|
<td colspan="3">
|
||||||
<table class="box-full" border="0">
|
<table border="0">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="head" colspan="4">Charges Detail:</td>
|
<td class="head" colspan="4">Charges Detail:</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php foreach ($io->items_service_periods() as $rs => $items) { ?>
|
<?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><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>
|
||||||
<?php if ($rs) { ?>
|
<?php if ($rs) { ?>
|
||||||
<td><?php echo StaticList_RecurSchedule::display($rs); ?></td>
|
<td><?php echo StaticList_RecurSchedule::display($rs); ?></td>
|
||||||
<td colspan="1"><?php printf('%s Service(s)',count($items)); ?></td>
|
<td><?php printf('%s Service(s)',count($items)); ?></td>
|
||||||
<?php } else { ?>
|
|
||||||
<td colspan="2">Other Items</td>
|
|
||||||
<?php } ?>
|
|
||||||
<td> </td>
|
<td> </td>
|
||||||
|
<?php } else { ?>
|
||||||
|
<td colspan="3">Other Items</td>
|
||||||
|
<?php } ?>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div id="detail_toggle_<?php echo $rs; ?>">
|
<div id="detail_toggle_<?php echo $rs; ?>">
|
||||||
<table class="box-full" border="0">
|
<table class="box-full" border="0">
|
||||||
<?php if ($items) { ?>
|
<?php if ($items) {
|
||||||
<?php foreach ($io->items_services($items) as $sid => $ito) { ?>
|
foreach ($items as $k=>$service_id) {
|
||||||
<!-- Product Information -->
|
$i = 0;
|
||||||
|
$lp = NULL;
|
||||||
|
$ito_tax = NULL;
|
||||||
|
foreach ($io->items_service($service_id) as $ito) {
|
||||||
|
$ito_tax = $ito;
|
||||||
|
// Our first line we show the Service Details
|
||||||
|
if ($ito->item_type == 0 AND $ito->product_id != $lp) {
|
||||||
|
$lp = $ito->product_id; ?>
|
||||||
|
<!-- Service Information -->
|
||||||
<tr class="head">
|
<tr class="head">
|
||||||
<td><?php echo HTML::anchor('/user/service/view/'.$ito->service_id,$ito->service->id()); ?></td>
|
<td><?php echo HTML::anchor('/user/service/view/'.$ito->service_id,$ito->service->id()); ?></td>
|
||||||
<td colspan="5"><?php printf('%s - %s',$ito->product->name(),$ito->service->name()); ?> (<?php echo $ito->product_id; ?>)</td>
|
<td colspan="5"><?php printf('%s - %s',$ito->product->name(),$ito->service->name()); ?> (<?php echo $ito->product_id; ?>)</td>
|
||||||
<td class="right"><?php echo Currency::display($io->items_service_total($ito->service_id));?></td>
|
<td class="right"><?php echo ($i++==0 ? Currency::display($io->items_service_total($ito->service_id)) : ' ');?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- End Product Information -->
|
<!-- END Product Information -->
|
||||||
|
<?php } ?>
|
||||||
<?php foreach ($io->items_service($sid) as $ito) { ?>
|
|
||||||
<!-- Product Sub Information -->
|
<!-- Product Sub Information -->
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
@ -82,9 +96,8 @@
|
|||||||
<td><?php echo $ito->period();?></td>
|
<td><?php echo $ito->period();?></td>
|
||||||
<td class="right"><?php echo Currency::display($ito->subtotal());?> </td>
|
<td class="right"><?php echo Currency::display($ito->subtotal());?> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- End Product Sub Information -->
|
<!-- END Product Sub Information -->
|
||||||
<?php } ?>
|
<!-- Service Discount Information -->
|
||||||
|
|
||||||
<?php if ($ito->discount_amt) { ?>
|
<?php if ($ito->discount_amt) { ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4"> </td>
|
<td colspan="4"> </td>
|
||||||
@ -92,6 +105,45 @@
|
|||||||
<td class="right">(<?php echo Currency::display($io->items_service_discount($ito->service_id));?>)</td>
|
<td class="right">(<?php echo Currency::display($io->items_service_discount($ito->service_id));?>)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
<!-- END Service Discount Information -->
|
||||||
|
<?php } ?>
|
||||||
|
<?php if ($ito_tax) { ?>
|
||||||
|
<!-- Product Sub Items Tax -->
|
||||||
|
<tr>
|
||||||
|
<td colspan="4"> </td>
|
||||||
|
<td><?php echo _('Taxes'); ?></td>
|
||||||
|
<td class="right"><?php echo Currency::display($io->items_service_tax($ito->service_id));?> </td>
|
||||||
|
</tr>
|
||||||
|
<!-- END Product Sub Items Tax -->
|
||||||
|
<?php } ?>
|
||||||
|
<?php } ?>
|
||||||
|
<?php } ?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<?php } ?>
|
||||||
|
<?php if ($io->items_index('account')) { ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo HTML::image($mediapath->uri(array('file'=>'img/toggle-closed.png')),array('alt'=>'+')); ?></td>
|
||||||
|
<td colspan="2">Other Invoice Items</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td colspan="2">
|
||||||
|
<div id="detail_toggle_other">
|
||||||
|
<table class="box-full" border="0">
|
||||||
|
<?php foreach ($io->items_index('account') as $id => $ito) { ?>
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td><?php echo $ito->trannum();?></td>
|
||||||
|
<td><?php echo $ito->name();?></td>
|
||||||
|
<td><?php echo $ito->detail();?></td>
|
||||||
|
<td><?php echo $ito->period();?></td>
|
||||||
|
<td class="right"><?php echo Currency::display($ito->subtotal());?> </td>
|
||||||
|
</tr>
|
||||||
<!-- Product Sub Items Tax -->
|
<!-- Product Sub Items Tax -->
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4"> </td>
|
<td colspan="4"> </td>
|
||||||
@ -100,44 +152,59 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<!-- Product End Sub Items Tax -->
|
<!-- Product End Sub Items Tax -->
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<?php } ?>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
<!-- Invoice Sub Total -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="head" colspan="3">Sub Total of Items:</td>
|
<td class="head" colspan="2">Sub Total of Items:</td>
|
||||||
<td class="bold-right"><?php echo $io->subtotal(TRUE); ?> </td>
|
<td class="bold-right" colspan="2"><?php echo $io->subtotal(TRUE); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!-- END Invoice Sub Total -->
|
||||||
|
<?php if ($io->credit_amt) { ?>
|
||||||
|
<!-- Invoice Credits -->
|
||||||
|
<tr>
|
||||||
|
<td class="head" colspan="2">Credits Received:</td>
|
||||||
|
<td class="bold-right" colspan="2"><?php echo $io->display('credit_amt'); ?></td>
|
||||||
|
</tr>
|
||||||
|
<!-- END Invoice Credits -->
|
||||||
|
<?php } ?>
|
||||||
<?php if ($io->discount()) { ?>
|
<?php if ($io->discount()) { ?>
|
||||||
|
<!-- Invoice Discounts Total -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="head" colspan="3">Discounts:</td>
|
<td class="head" colspan="2">Discounts:</td>
|
||||||
<td class="bold-right">(<?php echo $io->discount(TRUE); ?>)</td>
|
<td class="bold-right" colspan="2">(<?php echo $io->discount(TRUE); ?>)</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!-- END Invoice Discounts Total -->
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
<!-- Invoice Taxes Total -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="head" colspan="4">Taxes Included:</td>
|
<td class="head" colspan="4">Taxes Included:</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php foreach ($io->tax_summary() as $tid => $amount) {
|
||||||
foreach ($io->tax_summary() as $tid => $amount) {
|
$m = ORM::factory('tax',$tid); ?>
|
||||||
$m = ORM::factory('tax',$tid);
|
|
||||||
?>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td colspan="2"><?php echo $m->description; ?></td>
|
<td><?php echo $m->description; ?></td>
|
||||||
<td class="bold-right"><?php echo Currency::display($amount); ?> </td>
|
<td class="bold-right" colspan="2"><?php echo Currency::display($amount); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php }?>
|
<?php }?>
|
||||||
<!-- @todo Add discounts -->
|
<!-- END Invoice Taxes Total -->
|
||||||
|
<!-- Invoice Total -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="head" colspan="3">Total This Invoice:</td>
|
<td class="head" colspan="2">Total This Invoice:</td>
|
||||||
<td class="bold-right"><?php echo $io->total(TRUE); ?> </td>
|
<td class="bold-right" colspan="2"><?php echo $io->total(TRUE); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!-- END Invoice Total -->
|
||||||
|
<!-- Account Total Due -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="head" colspan="3">Total Outstanding This Account:</td>
|
<td class="head" colspan="2">Total Outstanding This Account:</td>
|
||||||
<td class="bold-right"><?php echo $io->account->invoices_due_total(NULL,TRUE); ?> </td>
|
<td class="bold-right" colspan="2"><?php echo $io->account->invoices_due_total(NULL,TRUE); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!-- END Account Total Due -->
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -167,7 +167,7 @@ class Model_Payment extends ORMOSB {
|
|||||||
if ($pio->changed()) {
|
if ($pio->changed()) {
|
||||||
$old_pio = ORM::factory('payment_item',$pio->id);
|
$old_pio = ORM::factory('payment_item',$pio->id);
|
||||||
|
|
||||||
if ($it = $pio->invoice->due()+ORM::factory('payment_item',$pio->id)->alloc_amt-$pio->alloc_amt < 0)
|
if (($it = $pio->invoice->due()+ORM::factory('payment_item',$pio->id)->alloc_amt-$pio->alloc_amt) < 0)
|
||||||
$msg .= ($msg ? ' ' : '').sprintf('Invoice %s over allocated by %3.2f.',$pio->invoice_id,$it);
|
$msg .= ($msg ? ' ' : '').sprintf('Invoice %s over allocated by %3.2f.',$pio->invoice_id,$it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ class Controller_Admin_Service extends Controller_TemplateDefault_Admin {
|
|||||||
'listwebservices'=>TRUE,
|
'listwebservices'=>TRUE,
|
||||||
'listinvoicesoon'=>TRUE,
|
'listinvoicesoon'=>TRUE,
|
||||||
'update'=>TRUE,
|
'update'=>TRUE,
|
||||||
|
'view'=>TRUE,
|
||||||
);
|
);
|
||||||
|
|
||||||
public function action_autolist() {
|
public function action_autolist() {
|
||||||
@ -591,5 +592,35 @@ class Controller_Admin_Service extends Controller_TemplateDefault_Admin {
|
|||||||
'data'=>'css/dhtml.calendar.css',
|
'data'=>'css/dhtml.calendar.css',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function action_view() {
|
||||||
|
list($id,$output) = Table::page(__METHOD__);
|
||||||
|
|
||||||
|
$so = ORM::factory('service',$id);
|
||||||
|
|
||||||
|
if (! $so->loaded() OR ! Auth::instance()->authorised($so->account_id,$so->affiliate_id)) {
|
||||||
|
$this->template->content = 'Unauthorised or doesnt exist?';
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$loutput = '';
|
||||||
|
|
||||||
|
$loutput .= View::factory($this->viewpath())
|
||||||
|
->set('so',$so);
|
||||||
|
|
||||||
|
Block::add(array(
|
||||||
|
'title'=>sprintf('Transaction History for %s: %s',$so->id(),$so->name()),
|
||||||
|
'body'=>$loutput,
|
||||||
|
));
|
||||||
|
|
||||||
|
$output .= View::factory('service/user/view')
|
||||||
|
->set('so',$so);
|
||||||
|
|
||||||
|
Block::add(array(
|
||||||
|
'title'=>sprintf('%s: %s',$so->id(),$so->service_name()),
|
||||||
|
'body'=>$output,
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -20,6 +20,7 @@ class Model_Service extends ORMOSB {
|
|||||||
'service_billing'=>array('far_key'=>'account_billing_id','foreign_key'=>'id'),
|
'service_billing'=>array('far_key'=>'account_billing_id','foreign_key'=>'id'),
|
||||||
);
|
);
|
||||||
protected $_has_many = array(
|
protected $_has_many = array(
|
||||||
|
'invoice_item'=>array('far_key'=>'id'),
|
||||||
'invoice'=>array('through'=>'invoice_item'),
|
'invoice'=>array('through'=>'invoice_item'),
|
||||||
);
|
);
|
||||||
protected $_belongs_to = array(
|
protected $_belongs_to = array(
|
||||||
@ -118,6 +119,10 @@ class Model_Service extends ORMOSB {
|
|||||||
return $plugin->admin_update();
|
return $plugin->admin_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function transactions() {
|
||||||
|
return $this->invoice_item->order_by('date_start,date_stop')->find_all();
|
||||||
|
}
|
||||||
|
|
||||||
/** LIST FUNCTIONS **/
|
/** LIST FUNCTIONS **/
|
||||||
|
|
||||||
private function _list_active() {
|
private function _list_active() {
|
||||||
|
41
modules/service/views/service/admin/view.php
Normal file
41
modules/service/views/service/admin/view.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!-- @todo NEEDS TO BE TRANSLATED -->
|
||||||
|
<table class="box-left" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td class="head" colspan="2">Transactions for this service</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>ID</td>
|
||||||
|
<td>Invoice</td>
|
||||||
|
<td>Product</td>
|
||||||
|
<td>IT</td>
|
||||||
|
<td>RS</td>
|
||||||
|
<td>Start</td>
|
||||||
|
<td>Stop</td>
|
||||||
|
<td>Desc</td>
|
||||||
|
<td>Charge</td>
|
||||||
|
<td>Quantity</td>
|
||||||
|
</tr>
|
||||||
|
<?php $lp=NULL;$i=0; foreach ($so->transactions() as $iio) { ?>
|
||||||
|
<?php if (! is_null($iio->product_id) AND $lp != $iio->product_id) {
|
||||||
|
$lp = $iio->product_id; ?>
|
||||||
|
<tr class="<?php echo $i++%2 ? 'odd' : 'even'; ?>">
|
||||||
|
<td class="head" colspan="10"><?php echo sprintf('%s: %s',$iio->product_id,$iio->product->name()); ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php } ?>
|
||||||
|
<tr class="<?php echo $i++%2 ? 'odd' : 'even'; ?>">
|
||||||
|
<td class="icon" width="20px"><?php echo $iio->id; ?></td>
|
||||||
|
<td class="data"><?php echo HTML::anchor('/user/invoice/view/'.$iio->invoice_id,$iio->invoice_id); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('product_id'); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('item_type'); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('recurring_schedule'); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('date_start'); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('date_stop'); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('product_name'); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('price_base'); ?></td>
|
||||||
|
<td class="data"><?php echo $iio->display('quantity'); ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php } ?>
|
||||||
|
</table>
|
Reference in New Issue
Block a user