/**
  * Toggles whether the user is checked in or not.
  *
  * @param \WP_REST_Request $request
  * @return \WP_Error|\WP_REST_Response
  */
 protected function _create_checkin_checkout_object(\WP_REST_Request $request)
 {
     $reg_id = $request->get_param('REG_ID');
     $dtt_id = $request->get_param('DTT_ID');
     $force = $request->get_param('force');
     if ($force == 'true') {
         $force = true;
     } else {
         $force = false;
     }
     $reg = \EEM_Registration::instance()->get_one_by_ID($reg_id);
     if (!$reg instanceof \EE_Registration) {
         return $this->send_response(new \WP_Error('rest_registration_toggle_checkin_invalid_id', sprintf(__('You cannot checkin registration with ID %1$s because it doesn\'t exist.', 'event_espresso'), $reg_id), array('status' => 422)));
     }
     if (!\EE_Capabilities::instance()->current_user_can('ee_edit_checkin', 'rest_api_checkin_endpoint', $reg_id)) {
         return $this->send_response(new \WP_Error('rest_user_cannot_toggle_checkin', sprintf(__('You are not allowed to checkin registration with ID %1$s.', 'event_espresso'), $reg_id), array('status' => 403)));
     }
     $success = $reg->toggle_checkin_status($dtt_id, !$force);
     if ($success === false) {
         //rely on EE_Error::add_error messages to have been added to give more data about hwy it failed
         return $this->send_response(new \WP_Error('rest_toggle_checkin_failed', __('Registration checkin failed. Please see additional error data.', 'event_espresso')));
     }
     $checkin = \EEM_Checkin::instance()->get_one(array(array('REG_ID' => $reg_id, 'DTT_ID' => $dtt_id), 'order_by' => array('CHK_timestamp' => 'DESC')));
     if (!$checkin instanceof \EE_Checkin) {
         return $this->send_response(new \WP_Error('rest_toggle_checkin_error', sprintf(__('Supposedly we created a new checkin object for registration %1$s at datetime %2$s, but we can\'t find it.', 'event_espresso'), $reg_id, $dtt_id)));
     }
     $requested_version = $this->get_requested_version($request->get_route());
     $get_request = new \WP_REST_Request('GET', \EED_Core_Rest_Api::ee_api_namespace . $requested_version . '/checkins/' . $checkin->ID());
     $get_request->set_url_params(array('id' => $checkin->ID()));
     return Read::handle_request_get_one($get_request);
 }
 /**
  * This method verifies whether the user can checkin for the given datetime considering the max uses value set on the ticket.
  *
  * To do this,  a query is done to get the count of the datetime records already checked into.  If the datetime given does
  * not have a check-in record and checking in for that datetime will exceed the allowed uses, then return false.  Otherwise return true.
  *
  * @param int | EE_Datetime  $DTT_OR_ID  The datetime the registration is being checked against
  * @return bool   true means can checkin.  false means cannot checkin.
  */
 public function verify_can_checkin_against_TKT_uses($DTT_OR_ID)
 {
     $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
     if (!$DTT_ID) {
         return false;
     }
     $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF;
     // if max uses is not set or equals infinity then return true cause its not a factor for whether user can check-in
     // or not.
     if (!$max_uses || $max_uses === EE_INF) {
         return true;
     }
     //does this datetime have a checkin record?  If so, then the dtt count has already been verified so we can just
     //go ahead and toggle.
     if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) {
         return true;
     }
     //made it here so the last check is whether the number of checkins per unique datetime on this registration
     //disallows further check-ins.
     $count_unique_dtt_checkins = EEM_Checkin::instance()->count(array(array('REG_ID' => $this->ID(), 'CHK_in' => true)), 'DTT_ID', true);
     // checkins have already reached their max number of uses
     // so registrant can NOT checkin
     if ($count_unique_dtt_checkins >= $max_uses) {
         EE_Error::add_error(__('Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
         return false;
     }
     return true;
 }
 /**
  * Deletes a single EE_Checkin row
  * @return void
  */
 protected function _delete_checkin_row()
 {
     $query_args = array('action' => 'registration_checkins', 'DTT_ID' => isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : 0, '_REGID' => isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : 0);
     if (!empty($this->_req_data['CHK_ID'])) {
         if (!EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
             EE_Error::add_error(__('Something went wrong and this check-in record was not deleted', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
         } else {
             EE_Error::add_success(__('Check-In record successfully deleted', 'event_espresso'));
         }
     } else {
         EE_Error::add_error(__('In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
     }
     $this->_redirect_after_action(FALSE, '', '', $query_args, TRUE);
 }
 /**
  * This retrieves all the Check-ins for the given parameters.
  * experimenting with having the query for the table values within the list table.
  *
  * @access protected
  * @param int     $per_page     How many to retrieve per page
  * @param bool    $count        Whether to return a count or not
  * @return EE_Checkin[]|int
  */
 protected function _get_checkins($per_page = 10, $count = FALSE)
 {
     $REG_ID = isset($this->_req_data['_REGID']) ? $this->_req_data['_REGID'] : FALSE;
     $DTT_ID = isset($this->_req_data['DTT_ID']) ? $this->_req_data['DTT_ID'] : FALSE;
     //if user does not have the capability for the checkins for this registration then get out!
     if (!EE_Registry::instance()->CAP->current_user_can('ee_read_checkin', 'espresso_registrations_registration_checkins', $REG_ID)) {
         return $count ? 0 : array();
     }
     //if no reg id then get out cause need a reg id
     if (empty($REG_ID) || empty($DTT_ID)) {
         throw new EE_Error(__('This route cannot be viewed unless registration and datetime IDs are included in the request (via REG_ID and DTT_ID parameters)', 'event_espresso'));
     }
     //set orderby
     $orderby = 'CHK_timestamp';
     //note that with this table we're only providing the option to orderby the timestamp value.
     $order = !empty($this->_req_data['order']) ? $this->_req_data['order'] : 'ASC';
     $current_page = isset($this->_req_data['paged']) && !empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
     $per_page = isset($this->_req_data['perpage']) && !empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $per_page;
     $limit = NULL;
     if (!$count) {
         $offset = ($current_page - 1) * $per_page;
         $limit = array($offset, $per_page);
     }
     $_where = array('REG_ID' => $REG_ID, 'DTT_ID' => $DTT_ID);
     $query_params = array($_where, 'order_by' => array($orderby => $order), 'limit' => $limit);
     //if no per_page value then we just want to return a count of all Check-ins
     if ($count) {
         return EEM_Checkin::instance()->count(array($_where));
     }
     return $count ? EEM_Checkin::instance()->count(array($_where)) : EEM_Checkin::instance()->get_all($query_params);
 }
 public function test_prepare_for_pretty_echoing()
 {
     $a_boolean_field = EEM_Checkin::instance()->field_settings_for('CHK_in');
     $this->assertEquals(__('Yes', 'event_espresso'), $a_boolean_field->prepare_for_pretty_echoing(true));
     $this->assertEquals(__('No', 'event_espresso'), $a_boolean_field->prepare_for_pretty_echoing(false));
 }
 /**
  *  Count registrations checked into (or out of) an event.
  *
  * @param int $EVT_ID event ID
  * @param boolean $checked_in whether to count registrations checked IN or OUT
  * @return int
  */
 public function count_registrations_checked_into_event($EVT_ID, $checked_in = true)
 {
     global $wpdb;
     //subquery to get latest checkin
     $query = $wpdb->prepare('SELECT ' . 'COUNT( DISTINCT checkins.REG_ID ) ' . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN' . '( SELECT ' . 'max( CHK_timestamp ) AS latest_checkin, ' . 'REG_ID AS REG_ID ' . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c ' . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d ' . 'ON c.DTT_ID=d.DTT_ID ' . 'WHERE d.EVT_ID=%d ' . 'GROUP BY REG_ID' . ') AS most_recent_checkin_per_reg ' . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID ' . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin ' . 'WHERE ' . 'checkins.CHK_in=%d', $EVT_ID, $checked_in);
     return (int) $wpdb->get_var($query);
 }