/**
  * 
  */
 public function SaveTransaction()
 {
     $ps_item_list = $this->request->getParameter('item_list', pString);
     $pa_item_list = json_decode($ps_item_list, true);
     $t_checkout = new ca_object_checkouts();
     $va_ret = array('status' => 'OK', 'errors' => array(), 'checkins' => array());
     foreach ($pa_item_list as $vn_i => $va_item) {
         if ($t_checkout->load($va_item['checkout_id'])) {
             $vn_object_id = $t_checkout->get('object_id');
             $t_object = new ca_objects($vn_object_id);
             if ($t_checkout->isOut()) {
                 try {
                     $t_checkout->checkin($vn_object_id, $va_item['note'], array('request' => $this->request));
                     $t_user = new ca_users($t_checkout->get('user_id'));
                     $vs_user_name = $t_user->get('ca_users.fname') . ' ' . $t_user->get('ca_users.lname');
                     $vs_borrow_date = $t_checkout->get('ca_object_checkouts.checkout_date', array('timeOmit' => true));
                     if ($t_checkout->numErrors() == 0) {
                         $va_ret['checkins'][] = _t('Returned <em>%1</em> (%2) borrowed by %3 on %4', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno'), $vs_user_name, $vs_borrow_date);
                     } else {
                         $va_ret['errors'][] = _t('Could not check in <em>%1</em> (%2): %3', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno'), join("; ", $t_checkout->getErrors()));
                     }
                 } catch (Exception $e) {
                     $va_ret['errors'][] = _t('<em>%1</em> (%2) is not out', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno'));
                 }
             } else {
                 $va_ret['errors'][] = _t('<em>%1</em> (%2) is not out', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno'));
             }
         }
     }
     $this->view->setVar('data', $va_ret);
     $this->render('checkin/ajax_data_json.php');
 }
 /**
  * Perform client services-related periodic tasks
  */
 public function hookPeriodicTask(&$pa_params)
 {
     $t_log = new Eventlog();
     $o_db = new Db();
     if (!(bool) $this->opo_config->get('enable_library_services')) {
         return true;
     }
     if ((bool) $this->opo_config->get('enable_object_checkout')) {
         $t_user = new ca_users();
         $t_checkout = new ca_object_checkouts();
         $vs_app_name = $this->opo_config->get('app_display_name');
         $vs_sender_name = $this->opo_library_services_config->get('notification_sender_name');
         $vs_sender_email = $this->opo_library_services_config->get('notification_sender_email');
         if (!is_array($va_administrative_email_addresses = $this->opo_library_services_config->getList('administrative_email_addresses'))) {
             $va_administrative_email_addresses = array();
         }
         // Periodic "coming due" notices
         if ($this->opo_library_services_config->get('send_coming_due_notices') && ($vs_interval = $this->opo_library_services_config->get('coming_due_interval'))) {
             try {
                 $va_items_by_user = ca_object_checkouts::getItemsDueWithin($vs_interval, array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('coming_due_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('coming_due_notification_interval')));
                 foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) {
                     if ($t_user->load($vn_user_id)) {
                         if ($vs_user_email = $t_user->get('email')) {
                             $vs_subject = _t('Notice of items coming due for return');
                             if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_coming_due.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) {
                                 // mark record
                                 foreach ($va_items_for_user as $va_item) {
                                     if ($t_checkout->load($va_item['checkout_id'])) {
                                         $t_checkout->setMode(ACCESS_WRITE);
                                         $t_checkout->set('last_sent_coming_due_email', _t('now'));
                                         $t_checkout->update();
                                         if ($t_checkout->numErrors()) {
                                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout coming due message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                         }
                                     } else {
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout coming due message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                     }
                                 }
                             }
                         } else {
                             // no email
                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                         }
                     } else {
                         // invalid user
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                     }
                 }
             } catch (Exception $e) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Invalid interval (%1) specified for coming due notices', $vs_interval), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
             }
         }
         // Periodic overdue notices
         if ($this->opo_library_services_config->get('send_overdue_notices')) {
             try {
                 $va_items_by_user = ca_object_checkouts::getOverdueItems(array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('overdue_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('overdue_notification_interval')));
                 foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) {
                     if ($t_user->load($vn_user_id)) {
                         if ($vs_user_email = $t_user->get('email')) {
                             $vs_subject = _t('Notice of overdue items');
                             if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_overdue.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) {
                                 // mark record
                                 foreach ($va_items_for_user as $va_item) {
                                     if ($t_checkout->load($va_item['checkout_id'])) {
                                         $t_checkout->setMode(ACCESS_WRITE);
                                         $t_checkout->set('last_sent_overdue_email', _t('now'));
                                         $t_checkout->update();
                                         if ($t_checkout->numErrors()) {
                                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout overdue message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                         }
                                     } else {
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout overdue message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                     }
                                 }
                             }
                         } else {
                             // no email
                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                         }
                     } else {
                         // invalid user
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                     }
                 }
             } catch (Exception $e) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Failed to get overdue list'), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
             }
         }
         // Notice when reservation becomes available
         if ($this->opo_library_services_config->get('send_reservation_available_notices')) {
             try {
                 $va_items_by_user = ca_object_checkouts::getReservedAvailableItems(array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('overdue_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('reservation_available_notification_interval')));
                 foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) {
                     if ($t_user->load($vn_user_id)) {
                         if ($vs_user_email = $t_user->get('email')) {
                             $vs_subject = _t('Notice of reserved available items');
                             if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_reservation_available.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) {
                                 // mark record
                                 foreach ($va_items_for_user as $va_item) {
                                     if ($t_checkout->load($va_item['checkout_id'])) {
                                         $t_checkout->setMode(ACCESS_WRITE);
                                         $t_checkout->set('last_reservation_available_email', _t('now'));
                                         $t_checkout->update();
                                         if ($t_checkout->numErrors()) {
                                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark reserved available message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                         }
                                     } else {
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark reserved available message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                                     }
                                 }
                             }
                         } else {
                             // no email
                             $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                         }
                     } else {
                         // invalid user
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
                     }
                 }
             } catch (Exception $e) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Failed to get reserved available list'), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask'));
             }
         }
     }
     return true;
 }
 * ----------------------------------------------------------------------
 *
 * Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
 * Copyright 2014 Whirl-i-Gig
 *
 * For more information visit http://www.CollectiveAccess.org
 *
 * This program is free software; you may redistribute it and/or modify it under
 * the terms of the provided license as published by Whirl-i-Gig
 *
 * CollectiveAccess is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTIES whatsoever, including any implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * This source code is free and modifiable under the terms of 
 * GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See
 * the "license.txt" file for details, or visit the CollectiveAccess web site at
 * http://www.CollectiveAccess.org
 *
 * ----------------------------------------------------------------------
 */
?>
	<h3 class='libraryCheckIn'><?php 
print _t('Library check in');
?>
:
	<div><?php 
print _t('Outstanding items: %1', ca_object_checkouts::numOutstandingCheckouts()) . "<br/>\n";
?>
</div>
	</h3>
 /**
  * Return list of pending reservations for object. Each item in the list is an array with the following elements
  * 
  *
  * @param array $pa_options No options are currently supported
  * @return array A list of pending reservations, or null if not object is loaded
  */
 public function getCheckoutReservations($pa_options = null)
 {
     if (!($vn_object_id = $this->getPrimaryKey())) {
         return null;
     }
     $t_checkout = new ca_object_checkouts();
     $va_reservations = $t_checkout->objectHasReservations($vn_object_id);
     $vb_is_reserved = is_array($va_reservations) && sizeof($va_reservations);
     return $vb_is_reserved ? $va_reservations : array();
 }
 /**
  *
  */
 public function getUserDetail()
 {
     $pn_user_id = $this->request->getParameter('user_id', pInteger);
     $ps_daterange = $this->request->getParameter('daterange', pString);
     $t_user = new ca_users($pn_user_id);
     $this->view->setVar('t_user', $t_user);
     if ($t_user->getPrimaryKey()) {
         $this->view->setVar('name', trim($t_user->get('fname') . ' ' . $t_user->get('lname')));
         $vs_item_display_template = "<unit relativeTo=\"ca_objects\"><l>^ca_objects.preferred_labels.name</l> (^ca_objects.idno)</unit>";
         // Get checkouts
         $this->view->setVar('checkouts', ca_object_checkouts::getOutstandingCheckoutsForUser($pn_user_id, $vs_item_display_template, $ps_daterange));
         // Get checkins
         $this->view->setVar('checkins', ca_object_checkouts::getCheckinsForUser($pn_user_id, $vs_item_display_template, $ps_daterange));
         // Get overdue
         $this->view->setVar('overdue_checkouts', ca_object_checkouts::getOverdueCheckoutsForUser($pn_user_id, $vs_item_display_template, $ps_daterange));
         // Get reservations
         $this->view->setVar('reservations', ca_object_checkouts::getOutstandingReservationsForUser($pn_user_id, $vs_item_display_template));
     } else {
         $this->view->setVar('name', "???");
     }
     $this->render('dashboard/user_detail_html.php');
 }
 /**
  * Return info via ajax on selected object
  */
 public function SaveTransaction()
 {
     $pn_user_id = $this->request->getParameter('user_id', pInteger);
     $ps_item_list = $this->request->getParameter('item_list', pString);
     $pa_item_list = json_decode($ps_item_list, true);
     $t_checkout = ca_object_checkouts::newCheckoutTransaction();
     $va_ret = array('status' => 'OK', 'total' => sizeof($pa_item_list), 'errors' => array(), 'checkouts' => array());
     $t_object = new ca_objects();
     foreach ($pa_item_list as $vn_i => $va_item) {
         if (!$t_object->load(array('object_id' => $va_item['object_id'], 'deleted' => 0))) {
             continue;
         }
         $vs_name = $t_object->getWithTemplate("^ca_objects.preferred_labels.name (^ca_objects.idno)");
         if ($va_checkout_info = $t_checkout->objectIsOut($va_item['object_id'])) {
             if ($va_checkout_info['user_id'] == $pn_user_id) {
                 // user already has item so skip it
                 $va_ret['errors'][$va_item['object_id']] = _t('User already has <em>%1</em>', $vs_name);
                 continue;
             }
             try {
                 $vb_res = $t_checkout->reserve($va_item['object_id'], $pn_user_id, $va_item['note'], array('request' => $this->request));
                 if ($vb_res) {
                     $va_ret['checkouts'][$va_item['object_id']] = _t('Reserved <em>%1</em>', $vs_name);
                 } else {
                     $va_ret['errors'][$va_item['object_id']] = _t('Could not reserve <em>%1</em>: %2', $vs_name, join('; ', $t_checkout->getErrors()));
                 }
             } catch (Exception $e) {
                 $va_ret['errors'][$va_item['object_id']] = _t('Could not reserve <em>%1</em>: %2', $vs_name, $e->getMessage());
             }
         } else {
             try {
                 $vb_res = $t_checkout->checkout($va_item['object_id'], $pn_user_id, $va_item['note'], $va_item['due_date'], array('request' => $this->request));
                 if ($vb_res) {
                     $va_ret['checkouts'][$va_item['object_id']] = _t('Checked out <em>%1</em>; due date is %2', $vs_name, $va_item['due_date']);
                 } else {
                     $va_ret['errors'][$va_item['object_id']] = _t('Could not check out <em>%1</em>: %2', $vs_name, join('; ', $t_checkout->getErrors()));
                 }
             } catch (Exception $e) {
                 $va_ret['errors'][$va_item['object_id']] = _t('Could not check out <em>%1</em>: %2', $vs_name, $e->getMessage());
             }
         }
     }
     $this->view->setVar('data', $va_ret);
     $this->render('checkout/ajax_data_json.php');
 }
 /**
  *
  */
 public static function getDashboardStatistics($ps_datetime = null, $pa_options = null)
 {
     if (!($o_db = caGetOption('db', $pa_options, null))) {
         $o_db = new Db();
     }
     if (!$ps_datetime) {
         $ps_datetime = _t('today');
     }
     $va_stats = array('numOverdueCheckouts' => ca_object_checkouts::numOverdueCheckouts($ps_datetime), 'overdueCheckoutUserList' => ca_object_checkouts::overdueCheckoutUserList($ps_datetime), 'numCheckouts' => ca_object_checkouts::numOutstandingCheckouts($ps_datetime), 'checkoutUserList' => ca_object_checkouts::outstandingCheckoutUserList($ps_datetime), 'numCheckins' => ca_object_checkouts::numCheckins($ps_datetime), 'checkinUserList' => ca_object_checkouts::checkinUserList($ps_datetime), 'numReservations' => ca_object_checkouts::numOutstandingReservations(), 'reservationUserList' => ca_object_checkouts::reservationUserList());
     //	Number of check-outs per day, week, month, year
     return $va_stats;
 }
 *
 * ----------------------------------------------------------------------
 */
$pn_user_id = $this->getVar('user_id');
$t_user = $this->getVar('t_user');
?>
	<h3 class='libraryCheckOut'><?php 
print _t('Library check out');
?>
:
	<div>
<?php 
if ($t_user->getPrimaryKey()) {
    print _t('Checkout for %1 (%2)', trim($t_user->get('fname') . ' ' . $t_user->get('lname')), $t_user->get('email'));
    if (is_array($va_checkouts = ca_object_checkouts::getOutstandingCheckoutsForUser($pn_user_id, "<unit relativeTo='ca_objects'><l>^ca_objects.preferred_labels.name</l> (^ca_objects.idno)</unit> <em>Due ^ca_object_checkouts.due_date%timeOmit=1</em>")) && sizeof($va_checkouts) > 0) {
        print "<div class='caLibraryCheckoutList'>\n";
        print "<h4>" . _t('User holds:') . "</h4>\n";
        print "<ul class='caLibraryCheckoutList'>\n";
        foreach ($va_checkouts as $va_checkout) {
            print "<li>" . $va_checkout['_display'] . "</li>\n";
        }
        print "</ul>\n";
        print "</div>\n";
    }
} else {
    // User not selected yet
    print _t('Items out (all users): %1', ca_object_checkouts::numOutstandingCheckouts()) . "<br/>\n";
}
?>
	</div>
	</h3>