Fixed bugs in study group calculations
This commit is contained in:
@@ -221,24 +221,32 @@ function booking_studygroups_calculate() {
|
|||||||
global $event;
|
global $event;
|
||||||
$attendees = array();
|
$attendees = array();
|
||||||
$working_list = array();
|
$working_list = array();
|
||||||
|
|
||||||
|
//delete from booking_studygroup_mapping;
|
||||||
|
//alter table booking_studygroup_mapping AUTO_INCREMENT=1;
|
||||||
|
|
||||||
//consider using a lock as per https://api.drupal.org/api/drupal/includes!lock.inc/group/lock/7
|
//consider using a lock as per https://api.drupal.org/api/drupal/includes!lock.inc/group/lock/7
|
||||||
|
|
||||||
//select all the study groups for this event id
|
//select all the study groups for this event id
|
||||||
$studygroups = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid", array(':eid' => $event->eid));
|
$studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid", array(':eid' => $event->eid));
|
||||||
|
$studygroups = $studygroups_query->fetchAllAssoc('sid');
|
||||||
|
|
||||||
//calculate the max number of attendees in a group
|
//calculate the max number of attendees in a group
|
||||||
$firstgroup = $studygroups[0];
|
$firstgroup = reset($studygroups);
|
||||||
$limit = variable_get('booking_regn_limit','500');
|
$limit = variable_get('booking_regn_limit','500');
|
||||||
$max_people = (int) ($limit / $firstgroup->booking_num_group_sessions);
|
//add an extra one to the maximum size, to cater for some larger groups when the number of people doesn't divide evenly
|
||||||
|
$max_people = (int) ($limit / $firstgroup->booking_num_group_sessions) + 1;
|
||||||
|
|
||||||
drupal_set_message(t('Fitting !num people in each group.', array('!num' => $max_people)));
|
//drupal_set_message(t('Fitting !num people in each group.', array('!num' => $max_people)));
|
||||||
|
|
||||||
//select all the attendees booked in
|
//select all the attendees booked in
|
||||||
$query = db_query("SELECT * FROM {booking_person} p left outer join {booking_leadhelp_list} l on p.nid = l.booking_node_id WHERE p.booking_event_id = :eid AND p.booking_status = 1",
|
$query = db_query("SELECT p.nid, p.booking_partner_id, p.booking_event_id, p.booking_status, l.booking_total_lead, l.booking_available_lead, l.booking_total_help, l.booking_available_help FROM {booking_person} p left outer join {booking_leadhelp_list} l on p.nid = l.booking_node_id WHERE p.booking_event_id = :eid AND p.booking_status = 1",
|
||||||
array(':eid' => $event->eid));
|
array(':eid' => $event->eid));
|
||||||
$attendees = $query->fetchAllAssoc('nid');
|
$attendees = $query->fetchAllAssoc('nid');
|
||||||
|
|
||||||
|
//create an array to keep track of the number of people in each session for this group
|
||||||
|
$session_count = array();
|
||||||
|
|
||||||
//select any entries already in the mapping table
|
//select any entries already in the mapping table
|
||||||
$group_mapping = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid));
|
$group_mapping = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid));
|
||||||
|
|
||||||
@@ -263,7 +271,8 @@ function booking_studygroups_calculate() {
|
|||||||
//iterate over each study group (eg Monday Tuesday Wednesday etc)
|
//iterate over each study group (eg Monday Tuesday Wednesday etc)
|
||||||
foreach ($studygroups as $group)
|
foreach ($studygroups as $group)
|
||||||
{
|
{
|
||||||
drupal_set_message(t('Processing study group !group.', array('!group' => $group->booking_studygroup_descrip)));
|
drupal_set_message(t('Processing study group !group with !sessions sessions.',
|
||||||
|
array('!group' => $group->booking_studygroup_descrip, '!sessions' => $group->booking_num_group_sessions)));
|
||||||
|
|
||||||
//create a temporary copy of the attendee list to work with for this study group
|
//create a temporary copy of the attendee list to work with for this study group
|
||||||
$working_list = array();
|
$working_list = array();
|
||||||
@@ -272,6 +281,10 @@ function booking_studygroups_calculate() {
|
|||||||
$obj = new ArrayObject( $working_list );
|
$obj = new ArrayObject( $working_list );
|
||||||
$it = $obj->getIterator();
|
$it = $obj->getIterator();
|
||||||
|
|
||||||
|
//clear the array keeping track of the number of people in each session for this group
|
||||||
|
for ($i = 1; $i <= $group->booking_num_group_sessions; $i++)
|
||||||
|
$session_count[$i] = 0;
|
||||||
|
|
||||||
//reset the iterator to starting position
|
//reset the iterator to starting position
|
||||||
$it->rewind();
|
$it->rewind();
|
||||||
|
|
||||||
@@ -290,7 +303,9 @@ function booking_studygroups_calculate() {
|
|||||||
{
|
{
|
||||||
if ($rewound == TRUE)
|
if ($rewound == TRUE)
|
||||||
{
|
{
|
||||||
watchdog('booking', "Already rewound once.");
|
//watchdog('booking', "Already rewound once.");
|
||||||
|
drupal_set_message(t("Error: Reached end of attendee list before allocating all study group leaders/helpers for group !group.",
|
||||||
|
array('!group' => $group->booking_studygroup_descrip)), 'error', FALSE);
|
||||||
//we've already gone back to the start once, don't do it again
|
//we've already gone back to the start once, don't do it again
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -315,15 +330,16 @@ function booking_studygroups_calculate() {
|
|||||||
$helper_found = FALSE;
|
$helper_found = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//get the current attendee element
|
//get the current attendee element
|
||||||
$current = $it->current();
|
$current = $it->current();
|
||||||
|
$key = $it->key();
|
||||||
//watchdog('booking', 'Attendee before leader check has id !id.', array('!id' => $it->key()));
|
//watchdog('booking', 'Attendee before leader check has id !id.', array('!id' => $it->key()));
|
||||||
|
|
||||||
//check if this attendee is a leader
|
//check if this attendee can be a leader
|
||||||
if ($current->processed == 0 && $current->booking_available_lead > 0 && $leader_found == FALSE)
|
if ($leader_found == FALSE && $current->processed == 0 && $current->booking_available_lead > 0)
|
||||||
{
|
{
|
||||||
drupal_set_message(t('Found available leader with id !id for session !session.', array('!id' => $it->key(), '!session' => $session_id)));
|
drupal_set_message(t('Found available leader with id !id for session !session (currently with !num people).',
|
||||||
|
array('!id' => $it->key(), '!session' => $session_id, '!num' => $session_count[$session_id])));
|
||||||
|
|
||||||
$leader_found = TRUE;
|
$leader_found = TRUE;
|
||||||
|
|
||||||
@@ -331,48 +347,68 @@ function booking_studygroups_calculate() {
|
|||||||
$current->session = $session_id;
|
$current->session = $session_id;
|
||||||
$current->processed = 1;
|
$current->processed = 1;
|
||||||
$current->is_leader = 1;
|
$current->is_leader = 1;
|
||||||
|
|
||||||
|
//keep track of the number of people in this study group session
|
||||||
|
//$session_count[$session_id] = $session_count[$session_id] + 1;
|
||||||
|
|
||||||
//decrement the number of available leading positions for this user in our master copy of the attendee list
|
//decrement the number of available leading positions for this user in our master copy of the attendee list
|
||||||
$attendees[$it->key()]->booking_available_lead = $attendees[$it->key()]->booking_available_lead - 1;
|
$attendees[$key]->booking_available_lead = $attendees[$key]->booking_available_lead - 1;
|
||||||
|
|
||||||
|
$partner_id = $current->booking_partner_id;
|
||||||
|
|
||||||
//Check for spouse of leader, allocate to this group also
|
//Check for spouse of leader, allocate to this group also
|
||||||
if ($current->booking_partner_id > 0)
|
if ($partner_id > 0)
|
||||||
{
|
{
|
||||||
//add the spouse to the same session and mark as processed in the temporary attendee list
|
//add the spouse to the same session and mark as processed in the temporary attendee list
|
||||||
drupal_set_message(t('Assigning spouse (id !spouse) of id !id to session !session.',
|
drupal_set_message(t('Assigning spouse (id !spouse) of id !id to session !session (currently with !num people).',
|
||||||
array('!id' => $it->key(), '!session' => $session_id, '!spouse' => $current->booking_partner_id)));
|
array('!id' => $it->key(), '!session' => $session_id, '!spouse' => $partner_id, '!num' => $session_count[$session_id])));
|
||||||
|
|
||||||
$spouse = $working_list[$current->booking_partner_id];
|
//$spouse = ;
|
||||||
$spouse->session = $session_id;
|
$working_list[$partner_id]->session = $session_id;
|
||||||
$spouse->processed = 1;
|
$working_list[$partner_id]->processed = 1;
|
||||||
|
//add two people to this session
|
||||||
|
$session_count[$session_id] = $session_count[$session_id] + 2;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//only add one person to this session
|
||||||
|
$session_count[$session_id] = $session_count[$session_id] + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//check if this attendee is a helper
|
//check if this attendee can be a helper
|
||||||
elseif ($current->processed == 0 && $current->booking_available_help > 0 && $helper_found == FALSE)
|
elseif ($helper_found == FALSE && $current->processed == 0 && $current->booking_available_help > 0)
|
||||||
{
|
{
|
||||||
drupal_set_message(t('Found available helper with id !id for session !session.', array('!id' => $it->key(), '!session' => $session_id)));
|
drupal_set_message(t('Found available helper with id !id for session !session (currently with !num people).',
|
||||||
|
array('!id' => $it->key(), '!session' => $session_id, '!num' => $session_count[$session_id])));
|
||||||
|
|
||||||
$helper_found = TRUE;
|
$helper_found = TRUE;
|
||||||
|
|
||||||
//assign leader to session and mark as processed in the temporary attendee list
|
//assign leader to session and mark as processed in the temporary attendee list
|
||||||
$current->session = $session_id;
|
$current->session = $session_id;
|
||||||
$current->processed = 1;
|
$current->processed = 1;
|
||||||
$current->is_helper = 1;
|
$current->is_helper = 1;
|
||||||
|
//$session_count[$session_id] = $session_count[$session_id] + 1;
|
||||||
|
|
||||||
//decrement the number of available helping positions for this user in our master copy of the attendee list
|
//decrement the number of available helping positions for this user in our master copy of the attendee list
|
||||||
$attendees[$it->key()]->booking_available_help = $attendees[$it->key()]->booking_available_help - 1;
|
$attendees[$key]->booking_available_help = $attendees[$key]->booking_available_help - 1;
|
||||||
|
|
||||||
|
$partner_id = $current->booking_partner_id;
|
||||||
|
|
||||||
//Check for spouse of helper, allocate to this group also
|
//Check for spouse of helper, allocate to this group also
|
||||||
if ($current->booking_partner_id > 0)
|
if ($partner_id > 0)
|
||||||
{
|
{
|
||||||
//add the spouse to the same session and mark as processed in the temporary attendee list
|
//add the spouse to the same session and mark as processed in the temporary attendee list
|
||||||
drupal_set_message(t('Assigning spouse (id !spouse) of id !id to session !session.',
|
drupal_set_message(t('Assigning spouse (id !spouse) of id !id to session !session.',
|
||||||
array('!id' => $it->key(), '!session' => $session_id, '!spouse' => $current->booking_partner_id)));
|
array('!id' => $it->key(), '!session' => $session_id, '!spouse' => $current->booking_partner_id)));
|
||||||
|
|
||||||
$spouse = $working_list[$current->booking_partner_id];
|
$session_count[$session_id] = $session_count[$session_id] + 2;
|
||||||
$spouse->session = $session_id;
|
$working_list[$partner_id]->session = $session_id;
|
||||||
$spouse->processed = 1;
|
$working_list[$partner_id]->processed = 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$session_count[$session_id] = $session_count[$session_id] + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//otherwise go to the next one
|
//otherwise go to the next one
|
||||||
else
|
else
|
||||||
@@ -380,9 +416,14 @@ function booking_studygroups_calculate() {
|
|||||||
$it->next();
|
$it->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//watchdog('booking', "Attendee list: @info", array('@info' => var_export($session_count, TRUE)));
|
||||||
|
|
||||||
//reset the iterator to starting position
|
//reset the iterator to starting position
|
||||||
$it->rewind();
|
$it->rewind();
|
||||||
|
|
||||||
|
//set our counter
|
||||||
|
$i = 1;
|
||||||
|
|
||||||
//iterate over the attendee list
|
//iterate over the attendee list
|
||||||
while ( $it->valid() )
|
while ( $it->valid() )
|
||||||
@@ -398,57 +439,103 @@ function booking_studygroups_calculate() {
|
|||||||
drupal_set_message("Ran out of attendees to process.");
|
drupal_set_message("Ran out of attendees to process.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($i > $group->booking_num_group_sessions)
|
||||||
|
$i = 1;
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
//Change this from a for loop
|
||||||
|
//to a check to see if a counter is greater than the number of sessions
|
||||||
|
//if it is then set it back to 1
|
||||||
|
|
||||||
//iterate over the session list
|
//iterate over the session list
|
||||||
for ($i = 1; $i <= $group->booking_num_group_sessions; $i++)
|
//for ($i = 1; $i <= $group->booking_num_group_sessions; $i++)
|
||||||
//for ($i = 1; $i <= 16; $i++)
|
//for ($i = 1; $i <= 16; $i++)
|
||||||
{
|
//{
|
||||||
//check we have attendees left
|
//check we have attendees left
|
||||||
if (! $it->valid() )
|
if (! $it->valid() )
|
||||||
|
{
|
||||||
|
drupal_set_message("Ran out of attendees to process.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check this session has room in it
|
||||||
|
$break_condition = false;
|
||||||
|
while ($session_count[$i] > $max_people)
|
||||||
|
{
|
||||||
|
drupal_set_message(t("Session ID !id is full, moving to next session for user id !nid", array('!id' => $i, '!nid' => $it->key())));
|
||||||
|
$i++;
|
||||||
|
//reset the counter if we go past the end
|
||||||
|
if ($i > $group->booking_num_group_sessions)
|
||||||
{
|
{
|
||||||
drupal_set_message("Ran out of attendees to process.");
|
$i = 1;
|
||||||
break;
|
//make sure we don't get stuck in an infinite loop - only go past the end once
|
||||||
}
|
if ($break_condition == true)
|
||||||
|
|
||||||
//get the current attendee element
|
|
||||||
$current = $it->current();
|
|
||||||
|
|
||||||
//assign this attendee to this session if unprocessed so far
|
|
||||||
if ($current->processed == 0)
|
|
||||||
{
|
|
||||||
drupal_set_message(t('Assigning person with id !id to session !session.', array('!id' => $it->key(), '!session' => $i)));
|
|
||||||
$current->session = $i;
|
|
||||||
$current->processed = 1;
|
|
||||||
|
|
||||||
//check if the attendee was married
|
|
||||||
if ($current->booking_partner_id > 0)
|
|
||||||
{
|
{
|
||||||
//add the spouse to the same session and mark as processed in the temporary attendee list
|
drupal_set_message("Ran out of sessions that aren't full to place attendees into.");
|
||||||
drupal_set_message(t('Assigning spouse (id !spouse) of id !id to session !session.',
|
break;
|
||||||
array('!id' => $it->key(), '!session' => $i, '!spouse' => $current->booking_partner_id)));
|
|
||||||
|
|
||||||
$spouse = $working_list[$current->booking_partner_id];
|
|
||||||
$spouse->session = $i;
|
|
||||||
$spouse->processed = 1;
|
|
||||||
}
|
}
|
||||||
|
$break_condition = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//move to the next unprocessed attendee in the list
|
/*
|
||||||
while ($it->valid() && $it->current()->processed == 1)
|
if ($session_count[$i] > $max_people)
|
||||||
$it->next();
|
{
|
||||||
|
drupal_set_message(t("Session ID !id is full, moving to next session for user id !nid", array('!id' => $i, '!nid' => $it->key())));
|
||||||
|
//$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//get the current attendee element
|
||||||
|
$current = $it->current();
|
||||||
|
|
||||||
|
//assign this attendee to this session if unprocessed so far
|
||||||
|
if ($current->processed == 0)
|
||||||
|
{
|
||||||
|
drupal_set_message(t('Assigning person with id !id to session !session (now with !num people).', array('!id' => $it->key(), '!session' => $i, '!num' => $session_count[$i])));
|
||||||
|
$current->session = $i;
|
||||||
|
$current->processed = 1;
|
||||||
|
$partner_id = $current->booking_partner_id;
|
||||||
|
|
||||||
} //finished looping through session list
|
//check if the attendee was married
|
||||||
|
if ($partner_id > 0)
|
||||||
|
{
|
||||||
|
//add the spouse to the same session and mark as processed in the temporary attendee list
|
||||||
|
drupal_set_message(t('Assigning spouse (id !spouse) of id !id to session !session.',
|
||||||
|
array('!id' => $it->key(), '!session' => $i, '!spouse' => $current->booking_partner_id)));
|
||||||
|
|
||||||
|
$working_list[$partner_id]->session = $i;
|
||||||
|
$working_list[$partner_id]->processed = 1;
|
||||||
|
$session_count[$i] = $session_count[$i] + 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$session_count[$i] = $session_count[$i] + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//move to the next unprocessed attendee in the list
|
||||||
|
while ($it->valid() && $it->current()->processed == 1)
|
||||||
|
{
|
||||||
|
//drupal_set_message(t("Skipping attendee ID !id, already processed.", array('!id' => $it->key())));
|
||||||
|
$it->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
//move to the next session
|
||||||
|
$i++;
|
||||||
|
|
||||||
|
//} //finished looping through session list
|
||||||
|
|
||||||
} //finished looping through attendees for this study group
|
} //finished looping through attendees for this study group
|
||||||
|
|
||||||
|
|
||||||
//iterate over the attendee list and write to the database the session they're assigned to
|
//iterate over the attendee list and write to the database the session they're assigned to
|
||||||
//use the multi-insert query type at https://drupal.org/node/310079
|
//use the multi-insert query type at https://drupal.org/node/310079
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$insert_query = db_insert('booking_studygroup_mapping')->fields(array('booking_eventid', 'booking_node_id',
|
$insert_query = db_insert('booking_studygroup_mapping')->fields(array('booking_eventid', 'booking_node_id',
|
||||||
'booking_studygroup_id', 'booking_session_id', 'booking_is_leader', 'booking_is_helper'));
|
'booking_studygroup_id', 'booking_session_id', 'booking_is_leader', 'booking_is_helper'));
|
||||||
|
|
||||||
@@ -466,12 +553,20 @@ function booking_studygroups_calculate() {
|
|||||||
'booking_is_leader' => $person->is_leader,
|
'booking_is_leader' => $person->is_leader,
|
||||||
'booking_is_helper' => $person->is_helper,
|
'booking_is_helper' => $person->is_helper,
|
||||||
);
|
);
|
||||||
$query->values($record);
|
$insert_query->values($record);
|
||||||
|
|
||||||
}
|
}
|
||||||
$query->execute();
|
$insert_query->execute();
|
||||||
|
|
||||||
|
|
||||||
|
//watchdog('booking', "Attendee list: @info", array('@info' => var_export($session_count, TRUE)));
|
||||||
|
|
||||||
|
//clear the arrays we've been using for this iteration
|
||||||
|
unset($session_count);
|
||||||
|
unset($working_list);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
} //finished processing study groups
|
} //finished processing study groups
|
||||||
|
|
||||||
//watchdog('booking', "Attendee list final version: @info", array('@info' => var_export($attendees, TRUE)));
|
//watchdog('booking', "Attendee list final version: @info", array('@info' => var_export($attendees, TRUE)));
|
||||||
@@ -499,34 +594,26 @@ function booking_studygroups_view_form($node, &$form_state, $group_id) {
|
|||||||
drupal_get_path('module', 'booking') . '/booking.css',
|
drupal_get_path('module', 'booking') . '/booking.css',
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($single_view == true)
|
//verify that $group_id is a number
|
||||||
{
|
if (! preg_match('/^[0-9]+$/', $group_id)) {
|
||||||
//verify that $group_id is a number
|
drupal_set_message("Error: Invalid study group ID supplied. Unable to view group membership.", 'error', FALSE);
|
||||||
if (! preg_match('/^[0-9]+$/', $group_id)) {
|
|
||||||
drupal_set_message("Error: Invalid study group ID supplied. Unable to view group membership.", 'error', FALSE);
|
|
||||||
drupal_goto('admin/config/booking');
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
//collect information on the study group
|
|
||||||
$group = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid and sid = :sid",
|
|
||||||
array(':eid' => $event->eid, ':sid' => $group_id))
|
|
||||||
->fetchObject();
|
|
||||||
|
|
||||||
if (! $group)
|
|
||||||
{
|
|
||||||
drupal_set_message("Error: Could not find matching study group ID. Unable to view group membership.", 'error', FALSE);
|
|
||||||
drupal_goto('admin/config/booking');
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
drupal_set_message("Page not yet implemented.", 'error', FALSE);
|
|
||||||
drupal_goto('admin/config/booking');
|
drupal_goto('admin/config/booking');
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//collect information on the study group
|
||||||
|
$group = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid and sid = :sid",
|
||||||
|
array(':eid' => $event->eid, ':sid' => $group_id))
|
||||||
|
->fetchObject();
|
||||||
|
|
||||||
|
if (! $group)
|
||||||
|
{
|
||||||
|
drupal_set_message("Error: Could not find matching study group ID. Unable to view group membership.", 'error', FALSE);
|
||||||
|
drupal_goto('admin/config/booking');
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
watchdog('booking', 'Study groups id: @info', array ('@info' => var_export($group_id, TRUE)));
|
||||||
|
|
||||||
$header = array(
|
$header = array(
|
||||||
'booking_session_id' => array('data' => t('Study Group Session'), 'field' => 'm.booking_session_id', 'sort' => 'asc'),
|
'booking_session_id' => array('data' => t('Study Group Session'), 'field' => 'm.booking_session_id', 'sort' => 'asc'),
|
||||||
|
Reference in New Issue
Block a user