diff --git a/application/classes/controller/admin/account.php b/application/classes/controller/admin/account.php new file mode 100644 index 00000000..56fd98d0 --- /dev/null +++ b/application/classes/controller/admin/account.php @@ -0,0 +1,40 @@ +TRUE, + ); + + /** + * Show a list of account logins + */ + public function action_listlog() { + Block::add(array( + 'title'=>_('Account Login Log'), + 'body'=>Table::display( + ORM::factory('account_log')->order_by('id','DESC')->find_all(), + 25, + array( + 'id'=>array('label'=>'ID','url'=>'admin/account/view/'), + 'date_orig'=>array('label'=>'Date'), + 'account->name()'=>array('label'=>'Account'), + 'ip'=>array('label'=>'IP Address'), + 'details'=>array('label'=>'Details'), + ), + array( + 'page'=>TRUE, + )), + )); + } +} +?> diff --git a/application/classes/controller/admin/welcome.php b/application/classes/controller/admin/welcome.php index 31e6fb38..4fbb5639 100644 --- a/application/classes/controller/admin/welcome.php +++ b/application/classes/controller/admin/welcome.php @@ -24,9 +24,9 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault { $o = ORM::factory('invoice'); Block_Sub::add(array( - 'title'=>'Invoices Overdue', + 'title'=>'Invoices Overdue - No Auto Billing', 'body'=>Table::display( - $o->list_overdue($t), + $o->list_overdue_billing($t), 25, array( 'due_date'=>array('label'=>'Due Date'), @@ -40,6 +40,23 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault { 'order'=>1, )); + Block_Sub::add(array( + 'title'=>'Invoices Overdue - Auto Billing', + 'body'=>Table::display( + $o->list_overdue_billing($t,TRUE), + 25, + array( + 'due_date'=>array('label'=>'Due Date'), + 'account->name()'=>array('label'=>'Account'), + 'account->display("status")'=>array('label'=>'Active'), + 'id()'=>array('label'=>'ID'), + 'due(TRUE)'=>array('label'=>'Amount Due','class'=>'right'), + ), + array('page'=>TRUE)), + 'position'=>2, + 'order'=>1, + )); + Block_Sub::add(array( 'title'=>'Invoices Due', 'body'=>Table::display( @@ -53,7 +70,7 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault { 'due(TRUE)'=>array('label'=>'Amount Due','class'=>'right'), ), array('show_other'=>'due()')), - 'position'=>2, + 'position'=>3, 'order'=>1, )); @@ -73,8 +90,8 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault { 'balance(TRUE)'=>array('label'=>'Balance','class'=>'right'), ), array('show_other'=>'balance()')), - 'position'=>3, - 'order'=>1, + 'position'=>1, + 'order'=>2, )); Block::add(array( diff --git a/application/classes/controller/lnapp/login.php b/application/classes/controller/lnapp/login.php index 76bb800e..a0122d32 100644 --- a/application/classes/controller/lnapp/login.php +++ b/application/classes/controller/lnapp/login.php @@ -168,6 +168,9 @@ class Controller_lnApp_Login extends Controller_TemplateDefault { 'USER_NAME'=>sprintf('%s %s',$mt->account->first_name,$mt->account->last_name), ); $et->send(); + + // Log the password reset + $ao->log('Password reset token sent'); } // Redirect to our password reset, the Auth will validate the token. diff --git a/application/classes/controller/lnapp/logout.php b/application/classes/controller/lnapp/logout.php index 1613d17b..26b6b82c 100644 --- a/application/classes/controller/lnapp/logout.php +++ b/application/classes/controller/lnapp/logout.php @@ -15,7 +15,9 @@ class Controller_lnApp_Logout extends Controller { public function action_index() { # If user already signed-in if (Auth::instance()->logged_in()!= 0) { + $ao = Auth::instance()->get_user(); Auth::instance()->logout(); + $ao->log('Logged Out'); Request::current()->redirect('login'); } diff --git a/modules/account/classes/controller/user/account.php b/modules/account/classes/controller/user/account.php index 3ebc0875..6db2be58 100644 --- a/modules/account/classes/controller/user/account.php +++ b/modules/account/classes/controller/user/account.php @@ -34,6 +34,10 @@ class Controller_User_Account extends Controller_TemplateDefault_User { )); $this->ao->save(); + + // Log the password reset + $this->ao->log('Password reset'); + Request::current()->redirect('login'); } else { @@ -50,6 +54,12 @@ class Controller_User_Account extends Controller_TemplateDefault_User { 'body'=>_('Your updates didnt pass validation.').'
'.$output, )); } + else + SystemMessage::add(array( + 'title'=>_('Record NOT updated'), + 'type'=>'info', + 'body'=>_('Your account has NOT been updated.') + )); Block::add(array( 'title'=>_('Password Reset'), diff --git a/modules/account/classes/model/account.php b/modules/account/classes/model/account.php index 4e439e80..c2694bea 100644 --- a/modules/account/classes/model/account.php +++ b/modules/account/classes/model/account.php @@ -112,5 +112,16 @@ class Model_Account extends Model_Auth_UserDefault { return $format ? Currency::display($result) : $result; } + + public function log($message) { + // Log the logout + $alo = ORM::factory('account_log'); + $alo->account_id = $this->id; + $alo->ip = $_SERVER['REMOTE_ADDR']; + $alo->details = $message; + $alo->save(); + + return $alo->saved(); + } } ?> diff --git a/modules/account/classes/model/account/log.php b/modules/account/classes/model/account/log.php new file mode 100644 index 00000000..7992b751 --- /dev/null +++ b/modules/account/classes/model/account/log.php @@ -0,0 +1,24 @@ +array(), + ); + + protected $_display_filters = array( + 'date_orig'=>array( + array('Config::datetime',array(':value')), + ), + ); +} +?> diff --git a/modules/account/classes/model/auth/userdefault.php b/modules/account/classes/model/auth/userdefault.php index 490d579e..50944557 100644 --- a/modules/account/classes/model/auth/userdefault.php +++ b/modules/account/classes/model/auth/userdefault.php @@ -55,7 +55,9 @@ class Model_Auth_UserDefault extends Model_Auth_User { * We can also do some other post-login actions here. * @todo Maybe we can do our session update here. */ - public function complete_login() {} + public function complete_login() { + return $this->log('Logged In'); + } /** * Test to see if a record has been changed diff --git a/modules/invoice/classes/controller/task/invoice.php b/modules/invoice/classes/controller/task/invoice.php index 41b03e81..87c2ab59 100644 --- a/modules/invoice/classes/controller/task/invoice.php +++ b/modules/invoice/classes/controller/task/invoice.php @@ -32,7 +32,7 @@ class Controller_Task_Invoice extends Controller_Task { $duelist .= View::factory('invoice/task/'.$tm.'_foot'); // Send our email - $et = Email_Template::instance('task_list_invoice_overdue'); + $et = Email_Template::instance('task_invoice_list_overdue'); // @todo Update this to be dynamic $et->to = array('account'=>array(1,68)); @@ -51,32 +51,93 @@ class Controller_Task_Invoice extends Controller_Task { // @todo This should go in a config somewhere $days = 5; $io = ORM::factory('invoice'); + $key = 'remind_due'; foreach ($io->list_due(time()-86400*$days) as $io) { // If we have already sent a reminder, we'll skip to the next one. - if ($io->remind('due_reminder') AND (is_null($x=$this->request->param('id')) OR $x != 'again')) + if ($io->remind($key) AND (is_null($x=$this->request->param('id')) OR $x != 'again')) continue; // Send our email - $et = Email_Template::instance('task_invoice_due_reminder'); + $et = Email_Template::instance('task_invoice_'.$key); $et->to = array('account'=>array($io->account_id)); $et->variables = array( 'DUE'=>$io->due(TRUE), + 'DUE_DATE'=>$io->display('due_date'), + 'FIRST_NAME'=>$io->account->first_name, 'INV_NUM'=>$io->refnum(), 'INV_URL'=>URL::site('user/invoice/view/'.$io->id,'http'), - 'DUE_DATE'=>$io->display('due_date'), - 'FIRSTNAME'=>$io->account->first_name, 'SITE_NAME'=>Config::sitename(), ); // @todo Record email log id if possible. if ($et->send()) - $io->set_remind('due_reminder',time()); + $io->set_remind($key,time()); } - $output = _('Overdue Reminders Sent.'); - $this->response->body($output); + $this->response->body(_('Due Reminders Sent.')); + } + + public function action_remind_overdue() { + $io = ORM::factory('invoice'); + $notice = $this->request->param('id'); + $x = NULL; + + if (preg_match('/:/',$notice)) + list($notice,$x) = explode(':',$notice); + + switch ($notice) { + case 1: + // @todo This should go in a config somewhere + $days = 2; + break; + + case 2: + // @todo This should go in a config somewhere + $days = 7; + break; + + case 3: + // @todo This should go in a config somewhere + $days = 21; + break; + + default: + $this->response->body(_('Unknown Remind Period: ').$notice); + return; + } + + $key = 'remind_overdue_'.$notice; + $template = 'task_invoice_'.$key; + + foreach ($io->list_overdue_billing(time()-86400*$days,FALSE) as $io) { + // If we have already sent a reminder, we'll skip to the next one. + if ($io->remind($key) AND (is_null($x) OR $x != 'again')) + continue; + + // Send our email + $et = Email_Template::instance('task_invoice_'.$key); + + $et->to = array('account'=>array($io->account_id)); + $et->variables = array( + 'DUE'=>$io->due(TRUE), + 'DUE_DATE'=>$io->display('due_date'), + 'EMAIL'=>'accounts@graytech.net.au', // @todo This should come from a config. + 'FIRST_NAME'=>$io->account->first_name, + 'INV_NUM'=>$io->refnum(), + 'INV_URL'=>URL::site('user/invoice/view/'.$io->id,'http'), + 'LATE_FEE'=>'5.50', // @todo This should come from a config file. + 'PAYMENTS_TABLE'=>$io->account->payment->list_recent_table(), + 'SITE_NAME'=>Config::sitename(), + ); + + // @todo Record email log id if possible. + if ($et->send()) + $io->set_remind($key,time()); + } + + $this->response->body(_('Overdue Reminders Sent: ').$notice); } } ?> diff --git a/modules/invoice/classes/model/invoice.php b/modules/invoice/classes/model/invoice.php index f38779b3..82f75114 100644 --- a/modules/invoice/classes/model/invoice.php +++ b/modules/invoice/classes/model/invoice.php @@ -337,7 +337,11 @@ class Model_Invoice extends ORMOSB { throw new Kohana_Exception('Reminder is not an array? (:reminder)',array(':remind',$this->reminders)); $remind = unserialize($this->reminders); - return isset($remind[$key]) ? $remind[$key] : FALSE; + + if (isset($remind[$key])) + return (is_array($remind[$key])) ? end($remind[$key]) : $remind[$key]; + else + return FALSE; } public function set_remind($key,$value,$add=FALSE) { @@ -346,20 +350,22 @@ class Model_Invoice extends ORMOSB { if (! trim($this->reminders)) { $remind = array(); - $remind[$key][] = $value; } else { if (! preg_match('/^a:/',$this->reminders)) throw new Kohana_Exception('Reminder is not an array? (:reminder)',array(':remind',$this->reminders)); $remind = unserialize($this->reminders); - - if ($add) - $remind[$key][] = $value; - else - $remind[$key] = $value; } + // If our value is null, we'll remove it. + if (is_null($value) AND isset($remind[$key])) + unset($remind[$key]); + elseif ($add) + $remind[$key][] = $value; + else + $remind[$key] = $value; + $this->reminders = serialize($remind); $this->save(); return $this->saved(); @@ -390,6 +396,25 @@ class Model_Invoice extends ORMOSB { return $this->_list_due($time,'<='); } + /** + * Return a list of invoices that are over their due date with/without auto billing + */ + public function list_overdue_billing($time=NULL,$billing=FALSE) { + $return = array(); + + foreach ($this->list_overdue($time) as $io) { + $i = FALSE; + foreach ($io->service->find_all() as $so) + if (($billing AND $so->account_billing_id) OR (! $billing AND ! $so->account_billing_id)) { + array_push($return,$io); + + break; + } + } + + return $return; + } + /** * Return a list of invoices that are due, excluding overdue. */ diff --git a/modules/payment/classes/model/payment.php b/modules/payment/classes/model/payment.php index 3ca51507..74c18e98 100644 --- a/modules/payment/classes/model/payment.php +++ b/modules/payment/classes/model/payment.php @@ -88,5 +88,32 @@ class Model_Payment extends ORMOSB { return $this->where('id','IN',$pi)->order_by('account_id')->find_all(); } + + public function list_recent_table() { + // @todo This should be in a config file. + $css = ''; + + return $css.Table::display( + $this->limit(10)->find_all(), + 25, + array( + 'id'=>array('label'=>'ID'), + 'date_payment'=>array('label'=>'Date'), + 'checkout->display("name")'=>array('label'=>'Method'), + 'total_amt'=>array('label'=>'Total','class'=>'right'), + 'balance(TRUE)'=>array('label'=>'Balance','class'=>'right'), + 'invoicelist()'=>array('label'=>'Invoices'), + ), + array( + 'type'=>'list', + )); + } } ?> diff --git a/modules/service/classes/model/service/domain.php b/modules/service/classes/model/service/domain.php new file mode 100644 index 00000000..ea45020a --- /dev/null +++ b/modules/service/classes/model/service/domain.php @@ -0,0 +1,59 @@ +array('foreign_key'=>'id','far_key'=>'domain_tld_id'), + 'host_registrar_plugin'=>array('foreign_key'=>'id','far_key'=>'domain_registrar_id'), + ); + protected $_belongs_to = array( + 'service'=>array(), + ); + + protected $_display_filters = array( + 'domain_expire'=>array( + array('Config::date',array(':value')), + ), + ); + + protected function _service_name() { + return sprintf('%s - %s','Domain',$this->name()); + } + + protected function _service_view() { + } + + /** + * Get specific service details for use in other modules + * For Example: Invoice + * + * @todo Make the rendered items configurable + */ + protected function _details($type) { + switch ($type) { + default: + throw new Kohana_Exception('Unkown detail request :type',array(':type'=>$type)); + } + } + + protected function _admin_update() { + } + + public function name() { + return sprintf('%s.%s',$this->domain_name,$this->host_tld->name); + } +} +?>