Completed hold time management in regCartSupport.php
authorChuck Scott <cscott@gaslightmedia.com>
Fri, 17 Nov 2017 21:11:20 +0000 (16:11 -0500)
committerChuck Scott <cscott@gaslightmedia.com>
Fri, 17 Nov 2017 21:11:20 +0000 (16:11 -0500)
Now adding hold times for new registrants
Updateing hold times when cart is re-displayed
Deleting registrants when no availability
Deleting holds for registrants who have been removed

classes/regCartSupport.php

index f9ab1f5..25e247a 100644 (file)
@@ -139,6 +139,8 @@ class GlmRegCartSupport
     /*
      * Retrieve a complete cart
      *
+     * This function starts by clearing any expored holds (reg_time_pending records)
+     *
      * Structure of returned data
      *
      * array (
@@ -150,8 +152,8 @@ class GlmRegCartSupport
      *      events          Array of events requested
      *          classes         Array of registration classes being requested
      *              rates           Array of rates selected for this event class
-     *                 registrants      Array of registrants selected for this rate - Also points to account for registrants in "accounts" array above
-     *
+     *                  registrants      Array of registrants selected for this rate - Also points to account for registrants in "accounts" array above
+     *                      hold            Array containing the reg_time_pending record data for this registrant - FALSE if none exits or it was purged
      * )
      *
      * @param integer $requestId Cart (request) ID
@@ -174,6 +176,9 @@ class GlmRegCartSupport
         $RequestRate = new GlmDataRegistrationsRegRequestRate($this->wpdb, $this->config);
         $RequestRegistrant = new GlmDataRegistrationsRequestRegistrant($this->wpdb, $this->config);
 
+        // First purge any expired pending registration holds
+        $this->purgeOldRegTimePending();
+
         // Clear cart data
         $this->cart = array(
             'status'        => false,           // Return status, default to false, true if valid request returned
@@ -233,11 +238,41 @@ class GlmRegCartSupport
                                 if ($this->cart['events'][$eventKey]['classes'][$classKey]['rates'][$rateKey]['registrants']) {
                                     foreach ($this->cart['events'][$eventKey]['classes'][$classKey]['rates'][$rateKey]['registrants'] as $registrantKey => $registrant) {
 
+                                        // Provide a more friendly date/time output
                                         $this->cart['events'][$eventKey]['classes'][$classKey]['rates'][$rateKey]['registrants'][$registrantKey]['timeReformatted'] = date('l m/d/Y g:i A', strtotime($registrant['event_time']));
 
-                                        // Add registrant account to accounts table
+                                        // Add registrant account to accounts table if needed
                                         $this->addAccountToCart($registrant['account']);
 
+                                        // Set default hold to false
+                                        $this->cart['events'][$eventKey]['classes'][$classKey]['rates'][$rateKey]['registrants'][$registrantKey]['hold'] = false;
+
+                                        // See if there's a hold for this registrant - expired ones should
+                                        $holds = $this->wpdb->get_results("
+                                               SELECT *
+                                               FROM ".GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_time_pending
+                                               WHERE registrant = ".$registrant['id']."
+                                        ;", ARRAY_A);
+
+                                        if (count($holds) > 0) {
+
+                                            // Scan though the holds for this registrant - should be only one
+                                            $updatedHold = false;
+                                            foreach ($holds as $hold) {
+
+                                                // If we already updated a hold for this registrant, delete this one
+                                                if ($updatedHold) {
+                                                    $this->deleteRegTimePending($hold);
+
+                                                // Otherwise add that to the registrant data
+                                                } else {
+                                                    $this->cart['events'][$eventKey]['classes'][$classKey]['rates'][$rateKey]['registrants'][$registrantKey]['hold'] = $hold;
+                                                    $updatedHold = true;
+                                                }
+                                            }
+
+                                        }
+
                                     } // Each Registrant
                                 }
 
@@ -307,9 +342,6 @@ class GlmRegCartSupport
             return $this->cart;
         }
 
-        // First purge any expired pending registration holds
-        $this->purgeOldRegTimePending();
-
         // Instantiate the classes we'll need
         $RegEvent = new GlmDataRegistrationsRegEvent($this->wpdb, $this->config);
         $RegTime = new GlmDataRegistrationsRegTime($this->wpdb, $this->config);
@@ -428,14 +460,19 @@ class GlmRegCartSupport
                                                     $removeRegistrant = true;
                                                 }
 
-                                                // Check the if registrant still has a time slot hold or can get one
-                                                // if () {
+                                                // Check the if registrant does not have a reg_time_pending entry
+                                                if (!$registrant['hold']) {
 
-                                                // } else {
+                                                    // Try to get a hold for this registrant
+                                                    $hold = $this->addRegTimePending($registrantKey, $registrant['reg_time']);
 
-                                                    // $removeRegistrant = true;
+                                                    // If that didn't work, mark this registrant for deletion
+                                                    if (!$hold) {
+                                                        $this->cart['messages'][] = "No availability for ".$registrant['fname'].' '.$registrant['fname'].". Registrant was removed.";
+                                                        $removeRegistrant = true;
+                                                    }
 
-                                                // }
+                                                }
 
                                                 // Check if registrant has an account
                                                 if (!isset($this->cart['accounts'][$registrant['account']])) {
@@ -486,7 +523,7 @@ class GlmRegCartSupport
 
                                         // If we don't have registrants
                                         if (!$haveRegistrants) {
-                                            $this->cart['messages'][] = 'Rate "'.$rate['rate_name'].'" has no registrants. This rate has been removed from the cart.';
+//                                            $this->cart['messages'][] = 'Rate "'.$rate['rate_name'].'" has no registrants. This rate has been removed from the cart.';
                                             $removeRate = true;
                                             $deleteRateNow = true;
                                         }
@@ -534,7 +571,7 @@ class GlmRegCartSupport
 
                             // If we don't have rates
                             if (!$haveRates) {
-                                $this->cart['messages'][] = 'Class "'.$class['class_name'].'" has no rates. This class has been removed from the cart.';
+//                                $this->cart['messages'][] = 'Class "'.$class['class_name'].'" has no rates. This class has been removed from the cart.';
                                 $removeClass = true;
                                 $deleteClassNow = true;
                             }
@@ -575,7 +612,7 @@ class GlmRegCartSupport
 
                     // If we don't have classes
                     if (!$haveClasses) {
-                        $this->cart['messages'][] = 'Event "'.$event['event_name'].'" has no classes. This event has been removed from the cart.';
+//                        $this->cart['messages'][] = 'Event "'.$event['event_name'].'" has no classes. This event has been removed from the cart.';
                         $removeEvent = true;
                         $deleteEventNow = true;
                     }
@@ -849,8 +886,8 @@ class GlmRegCartSupport
     /*
      * Purge old reg_time_pending entries
      *
-     * This function removes any expired reg_time_pending records and removes the counts from the attendees_pending field for
-     * the referenced reg_time table entry.
+     * This function removes any expired reg_time_pending records or those without matching registrants (been removed)
+     * and removes the counts from the attendees_pending field for the referenced reg_time table entry.
      *
      * This should be run before doing cart validation and in the back-end before displaying any availability numbers.
      *
@@ -861,32 +898,160 @@ class GlmRegCartSupport
 
         $purged = 0;
 
-        // Get all expired
-        $exp = $this->wpdb->get_results("
+        // Get all expired holds or holds without a matching registrant
+        $expHolds = $this->wpdb->get_results("
                SELECT *
                FROM ".GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_time_pending
                WHERE expire_time < NOW()
+               OR registrant NOT IN (
+                    SELECT DISTINCT(id)
+                      FROM ".GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_request_registrant
+                     WHERE id = registrant
+                  )
         ;", ARRAY_A);
 
-        foreach ($exp as $e) {
-            $res = $this->updateTimeEntryCounts($e['reg_time'], -1);
-            if ($res['success']) {
-                $this->wpdb->delete(
-                    GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_time_pending",
-                    array('id', $e['id'])
-                );
-                $purged++;
-            } else {
-                trigger_error('purgeOldRegTimePending() errors: '.$res['error'], E_USER_WARNING);
+        // If we have any expired holds
+        if (count($expHolds) > 0) {
+
+            // For each hold
+            foreach ($expHolds as $hold) {
+                $this->deleteRegTimePending($hold);
             }
+
         }
 
-        trigger_error('purgeOldRegTimePending() pending entries purged: '.$purged, E_USER_NOTICE);
+        // trigger_error('purgeOldRegTimePending() pending entries purged: '.$purged, E_USER_NOTICE);
 
         return;
 
     }
 
+    /*
+     * Obtain a hold for a particular registrant with a particular time entry
+     *
+     * This function removes a reg_time_pending record and removes the counts from the attendees_pending field for
+     * the referenced reg_time table entry.
+     *
+     * @param integer $registrantId ID of registrant
+     * @param integer $timeId ID of reg_time record
+     *
+     * @return array A reg_time_pending record - FALSE if unable to get hold
+     * @access public
+     */
+    public function addRegTimePending($registrantId, $timeId)
+    {
+
+        // Make sure attendee and reg_time id's are sane
+        $registrantId = ($registrantId - 0);
+        $timeId = ($timeId - 0);
+        if ($registrantId <= 0 || $timeId <= 0) {
+            return false;
+        }
+
+        // Get the reg_time entry
+        $timeData = $this->wpdb->get_row("
+               SELECT T.reg_event, T.attendee_max, T.attendee_count, T.attendees_pending, T.attendees_available, E.reg_hold_minutes
+               FROM ".GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_time T, ".GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_event E
+               WHERE T.id = $timeId
+              AND E.id = T.reg_event
+        ;", ARRAY_A);
+
+        // Check if no time record was found or there is no availability
+
+        if ($timeData == null || !isset($timeData['attendees_available']) || $timeData['attendees_available'] <= 0) {
+            return false;
+        }
+
+        // Create the reg_time_pending entry (hold)
+        $expTime = date('Y-m-d H:i:s', strtotime('+'.$timeData['reg_hold_minutes'].' minutes'));
+        $insertResult = $this->wpdb->insert(
+            GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX . 'reg_time_pending',
+            array(
+                'reg_event'     => $timeData['reg_event'],
+                'reg_time'      => $timeId,
+                'registrant'    => $registrantId,
+                'expire_time'   => $expTime
+            ),
+            array(
+                '%d',
+                '%d',
+                '%d',
+                '%s',
+                '%s'
+            )
+        );
+        if ($insertResult != 1) {
+            return false;
+        }
+
+        // Now get the new reg_time_pending entry
+        $rtpId = $this->wpdb->insert_id;
+
+        // SELECT * FROM `items` WHERE `id`= LAST_INSERT_ID()
+        $regTimePending = $this->wpdb->get_row("
+               SELECT * from ".GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_time_pending
+               WHERE id = $rtpId
+        ;", ARRAY_A);
+
+        // Update counts in reg_time record
+        $timeData['attendees_pending']++;
+        $timeData['attendees_available']--;
+
+        $updated = $this->wpdb->update(
+            GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX.'reg_time',
+            array(
+                'attendees_pending' => $timeData['attendees_pending'],
+                'attendees_available' => $timeData['attendees_available']
+            ),
+            array( 'id' => $timeId ),
+            array(
+                '%d',
+                '%d'
+            )
+            );
+
+        // If that didn't work, we'll quit and leave the time pending record (which will eventually be purged);
+        if (!$updated) {
+            return false;
+        }
+
+        return $regTimePending;
+
+    }
+
+    /*
+     * Delete Pending (hold)
+     *
+     * This function removes a reg_time_pending record and removes the counts from the attendees_pending field for
+     * the referenced reg_time table entry.
+     *
+     * @param array $hold A reg_time_pending record to be deleted
+     *
+     * @return boolean TRUE if deleted, FALSE if there was an error
+     * @access public
+     */
+    public function deleteRegTimePending($hold)
+    {
+
+        // Update the time entry counts
+        $res = $this->updateTimeEntryCounts($hold['reg_time'], -1);
+
+        // If that was successful, then delete the hold entry
+        if ($res['success']) {
+            $this->wpdb->delete(
+                GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_time_pending",
+                array('id' => $hold['id']),
+                array('%d')
+                );
+            return true;
+        }
+
+        trigger_error('purgeOldRegTimePending() errors: '.$res['error'], E_USER_WARNING);
+        return false;
+
+    }
+
+
     /*
      * Update inventory for a reg_time entry
      *
@@ -911,22 +1076,25 @@ class GlmRegCartSupport
         );
 
         // Get current time data
-        $time = $this->wpdb->get_results("
-               SELECT attendee_max, attendee_count, attendee_pending, attendee_available
+        $time = $this->wpdb->get_row("
+               SELECT attendee_max, attendee_count, attendees_pending, attendees_available
                FROM ".GLM_MEMBERS_REGISTRATIONS_PLUGIN_DB_PREFIX."reg_time
                WHERE id = $timeId
         ;", ARRAY_A);
-        if (!$time) {
+
+        if ($time == null) {
             $res['success'] = false;
             $res['error'] .= 'Invalid time entry ID or unable to retrieve. ';
+            return $res;
         }
 
         // Adjust balances
         $time['attendee_count'] += $counts;
         $time['attendees_pending'] += $pending;
-        $time['attendess_available'] = $time['attendee_max'] - ($time['attendee_count']+$time['attendees_pending']);
+        $time['attendees_available'] = $time['attendee_max'] - ($time['attendee_count']+$time['attendees_pending']);
 
         // Do sanity check on results
+
         if ($time['attendees_pending'] < 0 || $time['attendees_pending'] > ($time['attendee_max']-$time['attendee_count'])) {
             $res['success'] = false;
             $res['error'] .= 'Result has invalid pending attendees count.';
@@ -944,7 +1112,7 @@ class GlmRegCartSupport
                 array(
                     'attendee_count' => $time['attendee_count'],
                     'attendees_pending' => $time['attendees_pending'],
-                    'attendess_available' => $time['attendess_available']
+                    'attendees_available' => $time['attendees_available']
                 ),
                 array( 'id' => $timeId ),
                 array(