array(), 'invoice'=>array(), 'service'=>array() ); protected $_has_one = array( 'charge'=>array('far_key'=>'charge_id','foreign_key'=>'id') ); protected $_has_many = array( 'invoice_item_tax'=>array('far_key'=>'id') ); protected $_display_filters = array( 'date_orig'=>array( array('Config::date',array(':value')), ), 'date_start'=>array( array('Config::date',array(':value')), ), 'date_stop'=>array( array('Config::date',array(':value')), ), ); // Items belonging to an invoice private $subitems = array(); private $subitems_loaded = 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_loaded AND $this->loaded()) { $this->subitems['tax'] = $this->invoice_item_tax->find_all()->as_array(); $this->subitems_loaded = TRUE; } return $this; } // Display a transaction number public function trannum() { return sprintf('%03s-%06s',$this->item_type,$this->id); } // Display the period that a transaction applies public function period() { if ($this->date_start == $this->date_stop) return Config::date($this->date_start); else return sprintf('%s -> %s',Config::date($this->date_start),Config::date($this->date_stop)); } // Sum up the tax that applies to this invoice item public function tax() { $result = 0; foreach ($this->invoice_item_tax->find_all() as $iit) $result += $iit->amount; // @todo This shouldnt be required. if (! $result) $result += round($this->price_base*$this->quantity*.1,2); return Currency::round($result); } public function tax_items() { $result = array(); foreach ($this->invoice_item_tax->find_all() as $iit) { if (! isset($result[$iit->tax_id])) $result[$iit->tax_id] = 0; $result[$iit->tax_id] += $iit->amount; } return $result; } // This total of this item before discounts and taxes public function subtotal() { return Currency::round($this->price_base*$this->quantity); } // The total of all discounts public function discount() { return Currency::round($this->discount_amt); } public function total() { return Currency::round($this->subtotal()+$this->tax()-$this->discount()); } /** * Name for an invoice item */ public function name() { 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() { 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 125: return _('Payment Fee'); case 126: return _('Rounding'); case 127: return _('Late Payment Fee'); default: ''; } } public function invoice_detail_items() { switch ($this->item_type) { case 0: 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) { if (! $this->changed()) return; // Save the invoice item parent::save($validation); // Need to save the discounts associated with the invoice_item if ($this->saved()) { $iito = ORM::factory('Invoice_Item_Tax'); if ($this->subitems_loaded) { foreach (array('tax') as $i) foreach ($this->subitems[$i] as $io) if ($io->changed()) $io->save(); // Add TAX details } else // @todo tax parameters should come from user session foreach (Tax::detail(61,NULL,$this->subtotal()) as $tax) { $iito->clear(); $iito->invoice_item_id = $this->id; $iito->tax_id = $tax['id']; // @todo Rounding here should come from a global config $iito->amount = round($tax['amount'],2); if (! $iito->check()) throw new Kohana_Exception('Couldnt save tax for some reason - failed check()?'); $iito->save(); if (! $iito->saved()) throw new Kohana_Exception('Couldnt save tax for some reason - failed save()?'); } } else throw new Kohana_Exception('Couldnt save invoice_item for some reason?'); } } ?>