From 1598a272c47d90db736c614b8db88c0ca2458569 Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Mon, 30 Sep 2013 12:01:07 +1000 Subject: [PATCH] Initial project add --- booking.admin.inc | 348 +++++++++ booking.balance.inc | 235 ++++++ booking.confirm.inc | 276 +++++++ booking.constants.inc | 309 ++++++++ booking.emails.inc | 308 ++++++++ booking.events.inc | 293 ++++++++ booking.helper.inc | 798 ++++++++++++++++++++ booking.import_data.inc | 161 ++++ booking.info | 9 + booking.install | 363 +++++++++ booking.manual_payment.inc | 194 +++++ booking.module | 460 ++++++++++++ booking.paypal.inc | 242 ++++++ booking.prices.inc | 282 +++++++ booking.register.inc | 1421 ++++++++++++++++++++++++++++++++++++ booking.reports.inc | 404 ++++++++++ booking.tokens.inc | 567 ++++++++++++++ booking.variety.inc | 227 ++++++ 18 files changed, 6897 insertions(+) create mode 100644 booking.admin.inc create mode 100644 booking.balance.inc create mode 100644 booking.confirm.inc create mode 100644 booking.constants.inc create mode 100644 booking.emails.inc create mode 100644 booking.events.inc create mode 100644 booking.helper.inc create mode 100644 booking.import_data.inc create mode 100644 booking.info create mode 100644 booking.install create mode 100644 booking.manual_payment.inc create mode 100644 booking.module create mode 100644 booking.paypal.inc create mode 100644 booking.prices.inc create mode 100644 booking.register.inc create mode 100644 booking.reports.inc create mode 100644 booking.tokens.inc create mode 100644 booking.variety.inc diff --git a/booking.admin.inc b/booking.admin.inc new file mode 100644 index 0000000..79338c4 --- /dev/null +++ b/booking.admin.inc @@ -0,0 +1,348 @@ + 'fieldset', + '#title' => 'Email Addresses', + ); + + $form['email']['booking_from_email'] = array ( + '#type' => 'textfield', + '#title' => t('Sender Email Address'), + '#description' => t("The email address used as the source of outbound emails."), + '#size' => 60, + '#maxlength' => 150, + '#required' => TRUE, + '#default_value' => variable_get('booking_from_email',variable_get('site_mail', ini_get('sendmail_from'))), + ); + + $form['email']['booking_notify_email'] = array ( + '#type' => 'textfield', + '#title' => t('Notification Email Address(es)'), + '#description' => t("The email addresses to which registration notifications are sent."), + '#size' => 60, + '#maxlength' => 200, + '#required' => TRUE, + '#default_value' => variable_get('booking_notify_email',variable_get('site_mail', ini_get('sendmail_from'))), + ); + + $form['email']['booking_contact_email'] = array ( + '#type' => 'textfield', + '#title' => t('Contact Email Address'), + '#description' => t("The email address attendees are instructed to contact for additional information."), + '#size' => 60, + '#maxlength' => 150, + '#required' => TRUE, + '#default_value' => variable_get('booking_contact_email',variable_get('site_mail', ini_get('sendmail_from'))), + ); + + $form['email']['booking_logistics_email'] = array ( + '#type' => 'textfield', + '#title' => t('Logistics Email Address'), + '#description' => t("The email address used for logistics information."), + '#size' => 60, + '#maxlength' => 150, + '#required' => TRUE, + '#default_value' => variable_get('booking_logistics_email',variable_get('site_mail', ini_get('sendmail_from'))), + ); + $form['attendee'] = array ( + '#type' => 'fieldset', + '#title' => 'Attendee restrictions', + ); + + $form['attendee']['booking_max_dob'] = array ( + '#type' => 'date_select', + '#title' => t('Maximum Date of Birth'), + '#description' => t("The most recent date of birth you wish to allow into the event."), + '#default_value' => variable_get('booking_max_dob','1995-04-15 00:00:00'), + '#date_format' => 'd/m/Y', + '#date_label_position' => 'within', + '#date_year_range' => '-60:-10' + ); + + $form['attendee']['booking_regn_limit'] = array ( + '#type' => 'textfield', + '#title' => t('Registration limit'), + '#description' => t("Total number of attendees permitted."), + '#size' => 3, + '#maxlength' => 3, + '#required' => TRUE, + '#default_value' => variable_get('booking_regn_limit','500'), + ); + + $form['paypal'] = array ( + '#type' => 'fieldset', + '#title' => 'Paypal Settings', + ); + $form['paypal']['booking_paypal_account'] = array ( + '#type' => 'textfield', + '#title' => t('Account'), + '#default_value' => variable_get('booking_paypal_account', ''), + '#description' => '(email address)', + ); + $form['paypal']['booking_paypal_sandbox'] = array ( + '#type' => 'radios', + '#title' => t('Sandbox/Development mode'), + '#description' => t('When in development mode, the payment gateway will point at sandbox.paypal.com for testing purposes.'), + '#options' => array (0 => t('Off'), t('On')), + '#default_value' => variable_get('booking_paypal_sandbox', 0), + ); + $form['misc'] = array ( + '#type' => 'fieldset', + '#title' => 'Miscellaneous Settings', + ); + $form['misc']['booking_default_country'] = array ( + '#type' => 'select', + '#title' => t('Select Default Country'), + '#description' => t('Select default country for residential address.'), + '#options' => _booking_country_options(), + '#default_value' => variable_get('booking_default_country', 'Australia'), + ); + //TODO: reverse the logic of the values + $form['misc']['booking_auto_confirm_email'] = array ( + '#type' => 'radios', + '#title' => t('Automatic Registration Email'), + '#description' => t('Automatically send a confirmation email when a user registers for an event? (If No, email will be sent when status manually changed from Not Coming to Paid).'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_auto_confirm_email', 0), + ); + $form['misc']['booking_auto_show_on_lists'] = array ( + '#type' => 'radios', + '#title' => t('Show on lists once booked in?'), + '#description' => t('Immediately appear on bookedin/waiting lists even before payment is received?'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_auto_show_on_lists', 0), + ); + $form['misc']['booking_use_paypal'] = array ( + '#type' => 'radios', + '#title' => t('Use Paypal?'), + '#description' => t('Select whether to use paypal for automatic payment handling, or process payments manually.'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_use_paypal', 0), + ); + $form['misc']['booking_enable_combined_pricing'] = array ( + '#type' => 'radios', + '#title' => t('Use Combined Pricing?'), + '#description' => t('Select whether to combine pricing for married couples (Yes) or have each spouse pay separately (No).'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_enable_combined_pricing', 0), + ); + $form['misc']['booking_enable_medicare'] = array ( + '#type' => 'radios', + '#title' => t('Enable Medicare requirement?'), + '#description' => t('Select whether to require bookings to enter medicare details.'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_enable_medicare', 1), + ); + $form['misc']['booking_enable_tshirts'] = array ( + '#type' => 'radios', + '#title' => t('Enable t-shirt information?'), + '#description' => t('Select whether to include tshirt sizing in the booking form.'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_enable_tshirts', 0), + ); + $form['misc']['booking_enable_passport'] = array ( + '#type' => 'radios', + '#title' => t('Enable passport information?'), + '#description' => t('Select whether to include passport details in the booking form.'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_enable_passport', 0), + ); + $form['misc']['booking_enable_helpareas'] = array ( + '#type' => 'radios', + '#title' => t('Enable help area questions?'), + '#description' => t('Select whether to include questions about areas people are willing to help with in the booking form.'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_enable_helpareas', 0), + ); + $form['misc']['booking_enable_skills'] = array ( + '#type' => 'radios', + '#title' => t('Enable special skills information?'), + '#description' => t('Select whether to include questions about special skills people have in the booking form.'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_enable_skills', 0), + ); + $form['misc']['booking_enable_roommate'] = array ( + '#type' => 'radios', + '#title' => t('Enable room-mate selection?'), + '#description' => t('Select whether to allow attendees to list a preferred room-mate in the booking form.'), + '#options' => array (0 => t('No'), t('Yes')), + '#default_value' => variable_get('booking_enable_roommate', 0), + ); + + + + return system_settings_form($form); +} + +function booking_admin_validate($form, $form_state) { + //TODO: put back in when using booking start and end dates + /* +$booking_start = $form_state['values']['booking_start']; +$booking_end = $form_state['values']['booking_end']; + + +//create timestamps for comparison +$booking_start_ts = _date_to_ts( $booking_start ); +$booking_end_ts = _date_to_ts( $booking_end ); + + +//validate main conference start and end dates +if ($booking_start_ts > $booking_end_ts) { +form_set_error('booking_date_endbeforestart', t('You have selected a Conference end date that is before the Conference start date.')); +} else { +variable_set('booking_conference_dates', _date_range_to_string($booking_start, $booking_end)); +drupal_set_message( t('Conference date range: "!date"', array ('!date' => _date_range_to_string($booking_start, $booking_end)))); +} +*/ +} + + + +function booking_manual_email() +{ + global $event; + //see http://www.jaypan.com/blog/themeing-drupal-7-forms-tables-checkboxes-or-radios + $form = array (); + $options = array (); + $prefix = t("

Send a manual email to people registered for this event.

"); + $email_options_array = array(); + $email_options_array['registration'] = 'Manual Registration'; + $email_options_array['balance'] = 'Manual Balance Outstanding'; + $email_options_array['complete'] = 'Manual Payment Complete'; + + //add in the custom email types + for ($i = 1; $i <= CUSTOM_EMAIL_COUNT; $i++) + { + $email_options_array['custom' . $i] = variable_get('booking_email_subject_custom' . $i, $event->booking_eventname . ' custom ' . $i); + } + + $form['email-type'] = array( + '#type' => 'select', + '#title' => t('Email Type'), + '#required' => TRUE, + '#default_value' => '', + '#options' => $email_options_array, + ); + + $header = array ( + 'booking_nid' => array('data' => t('Booking ID')), + 'booking_name' => array('data' => t('Name')), + 'booking_email' => array('data' => t('Email Address')), + 'amount_paid' => array('data' => t('Amount Paid To Date')), + 'amount_reqd' => array('data' => t('Gross Payment Required')), + 'booking_status' => t('Status'), + 'booking_fully_paid' => t('Fully Paid?'), + ); + + $result = db_query("SELECT * FROM {booking_person} WHERE booking_event_id = :eid", + array(':eid' => $event->eid)); + + foreach($result as $data) + { + $options[$data->nid] = array ( + 'booking_nid' => l(t('!id', array('!id' => $data->nid)), t('node/!id', array('!id' => $data->nid))), + 'booking_name' => $data->booking_firstname . " " . $data->booking_lastname, + 'booking_email' => $data->booking_email, + 'amount_paid' => $data->booking_amount_paid, + 'amount_reqd' => $data->booking_total_pay_reqd, + 'booking_status' => _booking_status_generate($data->booking_status), + 'booking_fully_paid' => $data->booking_amount_paid < $data->booking_total_pay_reqd ? 'No' : 'Yes', + ); + } + + $form['table'] = array ( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + ); + + $form['submit'] = array ( + '#type' => 'submit', + '#value' => t('Send Email'), + ); + + return array ( + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + 'form' => $form, + ); +} + +function booking_manual_email_submit($form, &$form_state) { + $counter = 0; + $checkboxes = $form_state['values']['table']; //$values['booking_price_active']; + //watchdog('booking', 'Formstate when setting buttons: @info', array ('@info' => var_export($form_state['values'], TRUE))); + //watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE))); + + foreach($checkboxes as $key => $value) + { + if (is_numeric($key) && $value != 0) + { + //check if they exist in the database first + $person = db_query("SELECT person.nid " . + "FROM {booking_person} person " . + "WHERE nid = :nid", + array(':nid' => $key)) + ->fetchObject(); + + if ($person) + { + if ($form_state['values']['email-type'] == 'registration') + { + watchdog('booking', 'Processing a manual registration email to id @info', array ('@info' => $key)); + _booking_registration_email($key, false, true); + } + elseif ($form_state['values']['email-type'] == 'balance') + { + watchdog('booking', 'Processing a manual outstanding balance email to id @info', array ('@info' => $key)); + _booking_balance_payment_email($key); + } + elseif ($form_state['values']['email-type'] == 'complete') + { + watchdog('booking', 'Processing a manual registration complete email to id @info', array ('@info' => $key)); + _booking_registration_email($key, true, true); + } + elseif (strpos($form_state['values']['email-type'], 'custom') !== false) + { + watchdog('booking', 'Processing a @custom type email to id @info', array ('@custom' => $form_state['values']['email-type'], '@info' => $key)); + _booking_custom_email($key,$form_state['values']['email-type']); + } + /* + elseif ($form_state['values']['email-type'] == 'custom1') + { + watchdog('booking', 'Processing a custom1 type email to id @info', array ('@info' => $key)); + _booking_custom_email($key,$form_state['values']['email-type']); + } + elseif ($form_state['values']['email-type'] == 'custom2') + { + watchdog('booking', 'Processing a custom2 type email to id @info', array ('@info' => $key)); + _booking_custom_email($key,$form_state['values']['email-type']); + } + elseif ($form_state['values']['email-type'] == 'custom3') + { + watchdog('booking', 'Processing a custom3 type email to id @info', array ('@info' => $key)); + _booking_custom_email($key,$form_state['values']['email-type']); + } + */ + $counter++; + } + } + } + drupal_set_message("Sent manual email for $counter people.", 'status', FALSE); + watchdog('booking', "Sent manual email for $counter people."); +} \ No newline at end of file diff --git a/booking.balance.inc b/booking.balance.inc new file mode 100644 index 0000000..bfba7c6 --- /dev/null +++ b/booking.balance.inc @@ -0,0 +1,235 @@ +join('booking_price', 'pr', 'p.booking_payment_id = pr.pid'); + $query->condition('p.booking_tempid', arg(1), '=') + ->fields('p') + ->fields('pr', array('booking_price', 'booking_price_descrip')); + $person = $query->execute() + ->fetchObject(); + + if ($person) { + //maximum length for invoice id is 127 characters + $invoiceid = $person->nid . '_bal' . REQUEST_TIME . '_' . $person->booking_lastname . '-' . $person->booking_firstname; + $invoiceid = substr($invoiceid, 0, 126); + } else { + drupal_set_message("Unable to find matching session ID " . arg(1), 'error', FALSE); + return ""; + } + + $tokens = booking_define_personspecific_tokens($person); + $tokens['paypal-total-form'] = _booking_paypal_form($person, $invoiceid, $tokens['paypal-total-amount'], "Pay Balance"); + + //Calculate the amount outstanding + //watchdog('booking', 'Booking Balance form calculating amount owing'); + //$amount_owing = _booking_amount_owing($person->nid); + + //If the amount outstanding is zero, then display information to that effect. + if ($tokens['paypal-total-amount'] == 0) + { + $output = token_replace(variable_get('booking_regn_balance_page_paid'), $tokens); + } + else + { + $output = token_replace(variable_get('booking_regn_balance_page'), $tokens); + } + + //optional additional text for married people + if ($person->booking_married == 'Y') + { + $output .= token_replace(variable_get('booking_regn_balance_married_text'), $tokens); + } + + //put all the bits together + $return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output)); + //$return_array[] = array('form' => $paypal_form); + + //return the form + return $return_array; + +} + + +/** + * Confirmation page for event registration + */ + +/* +function old_booking_balance_page() { + global $event; + $output = ""; + $waiting_list = False; + $already_paid = false; + $amount_owing = 0; + $return_array = array(); + $output = ""; + + //verify that arg(1) is a uuid + if (! preg_match('/^[0-9A-Fa-f\-]+$/', arg(1))) { + //parameter from url is not what we were expecting + drupal_set_message("Error: Invalid session ID supplied. Please use the contact us form to let us know.", 'error', FALSE); + return ""; + } + + //fetch details about the person + $person = db_query("SELECT person.nid, person.booking_event_id, person.booking_lastname, person.booking_firstname, price.booking_buttonid, price.booking_price, price.booking_price_descrip, " . + " person.booking_married, person.booking_partner_name, booking_partner_id, person.booking_amount_paid, person.booking_status " . + "FROM {booking_person} person, {booking_price} price " . + "WHERE booking_tempid = :tempid " . + "AND person.booking_payment_id = price.pid", + array(':tempid' => arg(1))) + ->fetchObject(); + + if ($person) { + //maximum length for invoice id is 127 characters + $invoiceid = $person->nid . '_bal' . REQUEST_TIME . '_' . $person->booking_lastname . '-' . $person->booking_firstname; + $invoiceid = substr($invoiceid, 0, 126); + } else { + drupal_set_message("Unable to find matching session ID " . arg(1), 'error', FALSE); + return ""; + } + + //set a flag for married couple + $married = $person->booking_partner_id > 0 ? TRUE : FALSE; + + if ($married) + $output .= t("


Hi Mr and Mrs !lastname. Welcome to the payment page for !event, God willing.

", + array('!firstname' => $person->booking_firstname, '!lastname' => $person->booking_lastname, '!event' => $event->booking_eventname)); + else + $output .= t("


Hi !firstname !lastname. Welcome to the payment page for !event, God willing.

", + array('!firstname' => $person->booking_firstname, '!lastname' => $person->booking_lastname, '!event' => $event->booking_eventname)); + + //figure out if we're in the right time period for discounted registration rates + $early = db_query("SELECT booking_earlybird_close FROM {booking_event} where eid = :eid", array( + ':eid' => $event->eid)) + ->fetchObject(); + if ($early->booking_earlybird_close > time()) + $earlybird_flag = TRUE; + else + $earlybird_flag = FALSE; + + //Calculate the amount outstanding + $amount_owing = _booking_amount_owing($person->nid); + + //If the amount outstanding is zero, then display information to that effect. + if ($amount_owing == 0) + { + $output .= t("

Our records indicate that you have already fully paid, so there is no need for you to take any further action.

"); + $return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output)); + return $return_array; + } + else + { + if ($earlybird_flag) + { + $output .= t("

Our records indicate that you have a balance owing of $!owing (including Paypal transaction fees) in order to secure your spot at !event.

", + array('!owing' => number_format($amount_owing, 2, '.', ''), '!event' => $event->booking_eventname)); + } + else + { + //this payment has missed the early bird rate + $output .= t("

Our records indicate that you currently have $!amount outstanding (including Paypal transaction fees) to complete your payment for !event," . + " since you have missed the earlybird-rate cutoff date.

", + array('!amount' => number_format($amount_owing, 2, '.', ''), '!event' => $event->booking_eventname, + '!earlybird-cutoff' => format_date($early->booking_earlybird_close, 'custom', 'd/m/Y') )); + } + + //$output .= t("

Our records indicate that you have a balance owing of $!owing in order to secure your spot at !event. ", + // array('!owing' => number_format($amount_owing, 2, '.', ''), '!event' => $event->booking_eventname)); + + if ($person->booking_status == 2) + { + $output .= t("

However, you are currently on the waiting list, and are not required to pay the balance until your place at !event is confirmed.

", + array('!event' => $event->booking_eventname)); + } + $output .= t("

Please use the button below to submit your final payment securely via Paypal.

"); + $output .= t("

Once we have received your payment, you will be sent an automatic confirmation email thanking you for paying your outstanding fees. " . + "If you are paying via Paypal's eCheque feature, please be aware that payments take 3-5 working days to clear, and you will not receive the confirmation email until that has occurred.

"); + } + + //put all the bits together + $return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output)); + $return_array[] = array('form' => drupal_get_form('balance_form', arg(1), $person, $invoiceid, $amount_owing)); + + //return the form + return $return_array; +} + + +function balance_form($node, &$form_state, $tempid, $person, $invoiceid, $amount_owing) { + + global $event; + //paypal specific settings + $vars = array( + 'module' => 'Booking System', + 'type' => $event->booking_eventname, + //'custom' => $data, + 'item_name' => $event->booking_eventname . ' ' . $person->booking_price_descrip . ' balance', + 'invoice' => $invoiceid, + 'no_shipping' => TRUE, + 'no_note' => TRUE, + 'currency_code' => 'AUD', + 'return' => url('bookingfinal', array('absolute' => TRUE)), + 'cancel_return' => url('balance/' . $tempid, array('absolute' => TRUE)), + 'rm' => '2', + 'amount' => $amount_owing, + 'last_name' => $person->booking_lastname, + 'first_name' => $person->booking_firstname, + 'cmd' => '_xclick', + 'notify_url' => url(BOOKING_PAYPAL_IPN_PATH, array('absolute' => TRUE)), + 'business' => variable_get('booking_paypal_account', '') + ); + + $form['#action'] = url(variable_get('booking_paypal_sandbox', 0) ? BOOKING_PAYPAL_SUBMIT_URL_SANDBOX : BOOKING_PAYPAL_SUBMIT_URL, array('absolute' => TRUE)); + + + foreach($vars as $name => $value) { + + // is this field a forms api element, or just a value? + + // if(is_array($value)) { + // $form[$name] = $value; + // $form[$name]['#name'] = $name; + // } + //else { + $form[$name] = array( + '#type' => 'hidden', + '#value' => $value, + ); + //} + } + + $form['submit'] = array( + '#type' => 'button', + '#value' => t('Continue to Paypal'), + ); + + watchdog('booking', 'Booking Balance payment: @info', array ('@info' => var_export($form, TRUE))); + + return $form; + +} + +*/ \ No newline at end of file diff --git a/booking.confirm.inc b/booking.confirm.inc new file mode 100644 index 0000000..3c9e79b --- /dev/null +++ b/booking.confirm.inc @@ -0,0 +1,276 @@ +join('booking_price', 'pr', 'p.booking_payment_id = pr.pid'); + $query->condition('p.booking_tempid', arg(1), '=') + ->fields('p') + ->fields('pr', array('booking_price', 'booking_price_descrip')); + $person = $query->execute() + ->fetchObject(); + +/* + $person = db_query("SELECT person.nid, person.booking_event_id, person.booking_lastname, person.booking_firstname, price.booking_buttonid, price.booking_price, price.booking_price_descrip, booking_partner_id, " . + " person.booking_married, person.booking_partner_name, person.booking_status " . + "FROM {booking_person} person, {booking_price} price " . + "WHERE booking_tempid = :tempid " . + "AND person.booking_payment_id = price.pid", + array(':tempid' => arg(1))) + ->fetchObject(); +*/ + + if ($person) { + //maximum length for invoice id is 127 characters + $invoiceid = $person->nid . '_' . $person->booking_event_id . '_' . $person->booking_lastname . '-' . $person->booking_firstname; + $invoiceid = substr($invoiceid, 0, 126); + } else { + drupal_set_message("Unable to find matching session ID " . arg(1), 'error', FALSE); + return ""; + } + + //check if this registration will be on the waiting list + if (_booking_check_bookings_full() == True || $person->booking_status == 2) + $waiting_list = TRUE; + + //Calculate the amount outstanding + //$amount_owing = _booking_amount_owing($person->nid); + + //populate tokens +/* + $tokens = array(); + $tokens['eventname'] = $event->booking_eventname; + $tokens['fname'] = ucwords(trim($person->booking_firstname)); + $tokens['booking-id'] = $person->nid; + $tokens['payment-transaction-desc'] = $person->nid . ' ' . $person->booking_lastname; + $tokens['payment-required'] = $person->booking_price; + $tokens['waitinglist-position'] = ""; + */ + $tokens = booking_define_personspecific_tokens($person); + + //TODO: add in the paypal forms as tokens + $tokens['paypal-deposit-form'] = _booking_paypal_form($person, $invoiceid, $tokens['paypal-deposit-amount'], "Pay Deposit"); + $tokens['paypal-total-form'] = _booking_paypal_form($person, $invoiceid, $tokens['paypal-total-amount'], "Pay Full Amount"); + + //watchdog('booking', 'Paypal form "@info"', array ('@info' => var_export($tokens['paypal-total-form'], TRUE))); + + //$tokens['paypal-total-form'] = drupal_get_form('_booking_paypal_form', arg(1), $person, $invoiceid, $tokens['paypal-total-amount']); + + if ($waiting_list == FALSE) + { + //watchdog('booking', 'Waiting list is false. Un-tokenised text is "@info"', array ('@info' => variable_get('booking_regn_confirm_page'))); + $output = token_replace(variable_get('booking_regn_confirm_page'), $tokens); + //$paypal_form = drupal_get_form('_booking_paypal_form_builder', $person, $invoiceid, $amount_owing, "Pay Full Amount"); + } + else + { + //calculate waiting list position token + /* + $waitinglist_query = db_query("SELECT count(*) as num_ppl FROM {booking_person} where booking_event_id = :eventid and (booking_status = 1 or booking_status = 2)", + array(':eventid' => $event->eid)) + ->fetchObject(); + $tokens['waitinglist-position'] = $waitinglist_query->num_ppl - variable_get('booking_regn_limit', 350) + 1; + */ + $output = token_replace(variable_get('booking_regn_confirm_waiting_page'), $tokens); + + //only offer the deposit amount + //TODO: query this from the booking_price table + //$paypal_form = drupal_get_form('_booking_paypal_form', arg(1), $person, $invoiceid, '50.00'); + } + + //optional additional text for married people + if ($person->booking_married == 'Y') + { + $output .= token_replace(variable_get('booking_regn_confirm_married_text'), $tokens); + } + + //put all the bits together + $return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output)); + //$return_array[] = array('form' => $paypal_form); + + //return the form + return $return_array; +} + + +/* + * ORIGINAL VERSION FROM STUDY WEEK + +function booking_confirm_page() { + global $event; + $output = ""; + $waiting_list = False; + $already_paid = false; + + $form_action = variable_get('booking_paypal_sandbox', 0) ? BOOKING_PAYPAL_SUBMIT_URL_SANDBOX : BOOKING_PAYPAL_SUBMIT_URL; + + //verify that arg(1) is a uuid + if (! preg_match('/^[0-9A-Fa-f\-]+$/', arg(1))) { + //parameter from url is not what we were expecting + drupal_set_message("Error: Invalid session ID supplied. Please use the contact us form to let us know.", 'error', FALSE); + return ""; + } + + //TODO: if the person says they're married, query to see if they're listed partner has already registered and paid + //if they have, then let the new registration person know their partner has already paid, and send them the confirmation email + + //fetch details about the person + $person = db_query("SELECT person.nid, person.booking_event_id, person.booking_lastname, person.booking_firstname, price.booking_buttonid, price.booking_price, price.booking_price_descrip, " . + " person.booking_married, person.booking_partner_name, person.booking_status " . + "FROM {booking_person} person, {booking_price} price " . + "WHERE booking_tempid = :tempid " . + "AND person.booking_payment_id = price.pid", + array(':tempid' => arg(1))) + ->fetchObject(); + + if ($person) { + //maximum length for invoice id is 127 characters + $invoiceid = $person->nid . '_' . $person->booking_event_id . '_' . $person->booking_lastname . '-' . $person->booking_firstname; + $invoiceid = substr($invoiceid, 0, 126); + } else { + drupal_set_message("Unable to find matching session ID " . arg(1), 'error', FALSE); + return ""; + } + + //check if this person is married and their partner has already paid the deposit + if ($person->booking_married == 'Y') + { + //temporary hack + $output .= t("

In your registration details, you indicated that you were married. Please note that both you and your spouse must pay a deposit and book in individually, " . + "although the total married couple of $!fee only needs to be paid once.

", + array('!fee' => $person->booking_price)); + + //watchdog('booking', 'Partner name "@info"', array ('@info' => var_export($person->booking_partner_name, TRUE))); + if (preg_match('/^(\w*?)\s+(\w*)/', $person->booking_partner_name, $matches)) + { + watchdog('booking', 'Spouse checking. Firstname: "!first", surname "!last"', + array ('!first' => $matches[1], '!last' => $matches[2])); + + //try and find their partner + + $spouse = db_query("SELECT person.nid, person.booking_amount_paid, person.booking_total_pay_reqd " . + "FROM {booking_person} person " . + "WHERE person.booking_married = 'Y' AND person.booking_firstname = :first " . + "AND person.booking_lastname = :last AND person.booking_event_id = :event", + array(':first' => $matches[1], ':last' => $matches[2], ':event' => $event->eid)) + ->fetchObject(); + if ($spouse && ($spouse->booking_amount_paid >= $spouse->booking_total_pay_reqd)) + { + //TODO: Fix this + watchdog('booking', 'Spouse checking. Paid: "!paid", Total Due "!total"', + array ('!paid' => $spouse->booking_amount_paid, '!total' => $spouse->booking_total_pay_reqd)); + if ($spouse->booking_amount_paid >= $spouse->booking_total_pay_reqd) + watchdog('booking', 'This is calculated as having paid fully.'); + else + watchdog('booking', 'This is calculated as having money outstanding.'); + //drupal_set_message('Our records indicate your spouse has already paid all money outstanding. ' . + // 'There is no need to make any further payment', $type = 'status'); + $already_paid = true; + } + elseif ($spouse) + { + watchdog('booking', 'Partner "!name" has already paid "!price".', + array ('!name' => $person->booking_partner_name, '!price' => $spouse->booking_amount_paid)); + } + + } + + } + + //fetch the info for the deposit only button + $deposit = db_query("SELECT price.booking_buttonid, price.booking_price, price.booking_price_descrip " . + "FROM {booking_price} price WHERE booking_eventid = :eventid and booking_depositonly = 1 and booking_price_active = 1", + array(':eventid' => $event->eid)) + ->fetchObject(); + + //check if this registration will be on the waiting list + if (_booking_check_bookings_full() == True || $person->booking_status == 2) + $waiting_list = TRUE; + + //$waiting_list = $person->booking_status == 2 ? TRUE : FALSE; + + //For testing only + //_booking_registration_email($person->nid); + + //TODO: Also have different options for people that have chosen married + + + //Have different options for waiting list, and no full payment button + if ($waiting_list == TRUE) + { + $waitinglist_query = db_query("SELECT count(*) as num_ppl FROM {booking_person} where booking_event_id = :eventid and (booking_status = 1 or booking_status = 2)", + array(':eventid' => $event->eid)) + ->fetchObject(); + $output .= t("

Unfortunately the bookings for !event have reached the maximum number of attendees. " . + "If you wish to reserve your place on the waiting list at number !waitnum, please pay the deposit using this paypal button:
", + array('!event' => $event->booking_eventname, '!waitnum' => $waitinglist_query->num_ppl - variable_get('booking_regn_limit', 350) + 1)); + } + else + { + $output .= t("

If you wish to only pay your deposit for !event at this stage, please click on this paypal button:
", + array('!event' => $event->booking_eventname)); + } + + //Paypal form for paying the deposit only + $output .= t('

', array('!url' => $form_action)); + $output .= t(''); + $output .= t('', array('!id' => $deposit->booking_buttonid)); + $output .= t('', array('!invoice' => $invoiceid)); + $output .= t('', array('!name' => $event->booking_eventname . ' ' . $person->booking_price_descrip . ' (Deposit)')); + $output .= t('', array('!text' => "Return to " . $event->booking_eventname . " website")); + //$output .= t('', array('!url' => "http://example.com/image.jpg")); + $output .= t(''); + $output .= t(''); + $output .= t('

'); + + //Full payment option, only show if $waiting_list is false + if ($waiting_list == false) + { + $output .= t("

Otherwise, you can submit the full payment of $!price via the paypal button below to complete your booking as a !price_descrip.

", + array('!price' => $person->booking_price, '!price_descrip' => $person->booking_price_descrip)); + $output .= t('
', array('!url' => $form_action)); + $output .= t(''); + $output .= t('', array('!id' => $person->booking_buttonid)); + $output .= t('', array('!invoice' => $invoiceid)); + //$output .= t('', array('!amount' => $person->booking_price)); + $output .= t('', array('!name' => $event->booking_eventname . ' ' . $person->booking_price_descrip)); + $output .= t('', array('!text' => "Return to " . $event->booking_eventname . " website")); + //TODO: Include the study week logo + //The URL of the 150x50-pixel image displayed as your logo in the upper left corner of the PayPal checkout pages. + //$output .= t('', array('!url' => "http://example.com/image.jpg")); + + $output .= t('', + array('!amount' => $person->booking_price)); + $output .= t(''); + $output .= t('
'); + } + + //cheque information + $output .= t("

 

"); + $output .= t("

Paypal is the preferred method of payment, but if you absolutely cannot pay via paypal, please send a cheque to the following address. "); + $output .= t("Cheques should be made payable to "Study Week".

"); + $output .= t("

!event
6 School Parade
PADSTOW NSW 2211
Australia

", array('!event' => $event->booking_eventname)); + $output .= t("

Please include with the cheque the name you used when registering (!name), and your registration id (!id). You will not receive an email confirming your place until the cheque is received and processed.

", + array('!name' => $person->booking_lastname . ', ' . $person->booking_firstname, '!id' => $person->nid)); + return $output; +}*/ diff --git a/booking.constants.inc b/booking.constants.inc new file mode 100644 index 0000000..d238b58 --- /dev/null +++ b/booking.constants.inc @@ -0,0 +1,309 @@ + var_export($node, TRUE))); + + //waiting list has already been calculated, stored in node + $waiting_list = $node->booking_status == 2 ? TRUE : FALSE; + + //calculate the from email address + $from = t('!event Registrations ', array('!event' => $event->booking_eventname, + '!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from'))) + )); + + //send the registering person an email + $to = $node->booking_email; + $body = _booking_registration_email_generate($node, $waiting_list, $balance_payment, $manual); + if ($balance_payment == TRUE) + $subject = t('!event Payment Complete', array('!event' => $event->booking_eventname)); + else + $subject = t('!event Registration', array('!event' => $event->booking_eventname)); + + $params['subject'] = $subject; + $params['body'] = $body; + drupal_mail('booking', 'registration_mail', $to, $language, $params, $from); + drupal_mail('booking', 'registration_mail', 'it@coadcorp.com', $language, $params, $from); + + //send a notification email if we didn't automatically send one earlier + if (variable_get('booking_auto_confirm_email', 0) == 1) + { + _booking_regn_notifyonly_email($node, $balance_payment); + } + + } + +/** + * Function to send notification email only, nothing to the end user + * + * @param $node - variable representing the booking node + * @return nothing + */ + function _booking_regn_notifyonly_email($node, $balance_payment) +{ + global $event; + global $user; + $language = user_preferred_language($user); + + //calculate the from email address + $from = t('!event Registrations ', array('!event' => $event->booking_eventname, + '!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from'))) + )); + + //just put the registration info in this email to notify the appropriate people + $to = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from'))); + + if ($balance_payment == TRUE) + $params['subject'] = t('Registration Fully Paid: !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname)); + else + $params['subject'] = t('New Registration: !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname)); + + $params['body'] = _booking_details_email_summary($node); + drupal_mail('booking', 'registration_mail_notify', $to, $language, $params, $from); +} + +/** + * Function to generate email text to be sent to registrant after completing registration process + * + * @param $node - the registration node + * @param $booking_count - the number of bookings already made for this event id + * @param $waiting_list - whether this registration is on on the waiting list + * @return array containing email text + */ + function _booking_registration_email_generate($node, $waiting_list, $balance_payment, $manual) { + + global $event; + $tokens = booking_define_personspecific_tokens($node); + + if ($balance_payment == True) + { + $contact_message = token_replace(variable_get('booking_email_regn_complete_text'), $tokens); + } + elseif ($waiting_list == False) + { + $contact_message = token_replace(variable_get('booking_email_bookedin_text'), $tokens); + } + else + { + //booking is on the waiting list + $contact_message = token_replace(variable_get('booking_email_waitinglist_text'), $tokens); + } + + //$contact_message .= "\n\n" . t("!details", array('!details' => _booking_details_email_summary($node))); + return $contact_message; + +} + + +/** + * Function to generate email to be sent to the registrant to remind them of how much they owe, and include a payment link + * + * @param $nid - the registration node + */ +function _booking_balance_payment_email($nid) +{ + global $event; + global $user; + $language = user_preferred_language($user); + + //load the node matching this id + $node = node_load($nid); + $tokens = booking_define_personspecific_tokens($node); + + if ($tokens['amount-owing'] <= 0) + { + watchdog('booking', "Not sending amount owing email, since this person doesnt owe any money: @info", array('@info' => var_export($node, TRUE))); + return; + } + + //calculate the from email address + $from = t('!event Registrations ', array('!event' => $event->booking_eventname, + '!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from'))) + )); + + //calculate the remaining parameters + $to = $node->booking_email; + $subject = t('!event Payment Required', array('!event' => $event->booking_eventname)); + $params['subject'] = $subject; + + //retrieve the body of the email + $params['body'] = token_replace(variable_get('booking_email_paymentoutstanding_text'), $tokens) . + "\n\n" . t("!details", array('!details' => _booking_details_email_summary($node))); + + //send the email + drupal_mail('booking', 'registration_mail_bal_outstanding', $to, $language, $params, $from); + drupal_mail('booking', 'registration_mail_bal_outstanding', variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from'))), + $language, $params, $from); + drupal_mail('booking', 'registration_mail_bal_outstanding', 'it@coadcorp.com', $language, $params, $from); +} + +/** + * Function to generate email to be sent to the registrant based on custom email template configured in text tokens page + * + * @param $nid - the registration node + * @param $email_type - select which custom email template to use + * @return nothing + */ +function _booking_custom_email($nid, $email_type) +{ + global $event; + global $user; + $language = user_preferred_language($user); + $email_subject_variable = 'booking_email_subject_' . $email_type; + $email_body_variable = 'booking_email_' . $email_type; + + //load the node matching this id + $node = node_load($nid); + $tokens = booking_define_personspecific_tokens($node); + + //calculate the from email address + $from = t('!event Registrations ', array('!event' => $event->booking_eventname, + '!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from'))) + )); + + //calculate the remaining parameters + $to = $node->booking_email; + $subject = token_replace(variable_get($email_subject_variable, t('!event', array('!event' => $event->booking_eventname))), $tokens); + $params['subject'] = $subject; + + //retrieve the body of the email + $params['body'] = token_replace(variable_get($email_body_variable), $tokens); + + //send the email + drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from); + drupal_mail('booking', 'booking_email_custom', variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from'))), + $language, $params, $from); + drupal_mail('booking', 'booking_email_custom', 'it@coadcorp.com', $language, $params, $from); +} + + +/** + * Function to generate email to be sent to the registrant once they move from the waiting list to the coming list + * + * @param $nid - the registration node + */ +function _booking_promoted_from_waitinglist_email($nid) +{ + global $event; + global $user; + $language = user_preferred_language($user); + + //load the node matching this id + $node = node_load($nid); + $tokens = booking_define_personspecific_tokens($node); + + //calculate the from email address + $from = t('!event Registrations ', array('!event' => $event->booking_eventname, + '!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from'))) + )); + + //calculate the remaining parameters + $to = $node->booking_email; + $subject = t('!event Position Available', array('!event' => $event->booking_eventname)); + $params['subject'] = $subject; + + //retrieve the body of the email + $params['body'] = token_replace(variable_get($booking_email_waitinglistpromotion), $tokens); + + //send the email + drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from); + drupal_mail('booking', 'booking_email_custom', variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from'))), + $language, $params, $from); + drupal_mail('booking', 'booking_email_custom', 'it@coadcorp.com', $language, $params, $from); + +} + + +/* +function _booking_promoted_from_waitinglist_email_old($nid) +{ + global $event; + global $user; + $language = user_preferred_language($user); + //load the node matching this id + $node = node_load($nid); + + //figure out if we're in the right time period for discounted registration rates + $early = db_query("SELECT booking_earlybird_close FROM {booking_event} where eid = :eid", array( + ':eid' => $event->eid)) + ->fetchObject(); + if ($early->booking_earlybird_close > time()) + $amount_owing = _booking_amount_owing($node->nid); + else + { + $amount_owing = _booking_amount_owing($node->nid; + } + + //calcalate a new temp id to be configured for this user if required + if ($node->booking_tempid == '') + { + $tempid = _booking_uuidSecure(); + //update the user with this tempid + db_update('booking_person') + ->fields(array( + 'booking_tempid' => $tempid + )) + ->condition('nid', $node->nid) + ->execute(); + } + else + { + $tempid = $node->booking_tempid; + } + //calculate the booking balance URL for this user + $url = url('balance/' . $tempid, array('absolute' => TRUE)); + + //calculate the from email address + $from = t('!event Registrations ', array('!event' => $event->booking_eventname, + '!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from'))) + )); + + //calculate the body of the email + $contact_message[] = t("Dear !firstname,", array('!firstname' => ucwords(trim($node->booking_firstname)))); + $contact_message[] = t("We have some great news for you. A place at !event for you has just become available. ", + array('!event' => $event->booking_eventname)); + $contact_message[] = t("If you wish to secure your place at !event, please visit !link to make your final payment. " . + "Our records indicate that you currently have $!amount outstanding (including Paypal transaction fees).", + array('!amount' => number_format($amount_owing, 2, '.', ''), '!link' => $url, '!event' => $event->booking_eventname)); + $contact_message[] = t("Once we have received your payment, you will be sent an automatic confirmation email thanking you for paying your outstanding fees. " . + "If you are paying via Paypal's eCheque feature, please be aware that payments take 3-5 working days to clear, and you will not receive the confirmation email until that has occurred."); + $contact_message[] = t("Please don't hesitate to contact us if you have any queries by replying to this email. We look forward to seeing you (God Willing) at !event!!!", array('!event' => $event->booking_eventname)); + $contact_message[] = t("Love in Jesus,\n!event Registrations Team\n", array('!event' => $event->booking_eventname)); + $contact_message[] = t("________________________________________________________"); + $contact_message[] = t("The following information shows the details you entered when you registered. If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n________________________________________________________"); + $contact_message[] = t("!details", array('!details' => _booking_details_email_summary($node))); + + //turn the array into the body of the email + foreach ($contact_message as $key => $value) + $contact_message[$key] = wordwrap($value); + + //calculate the remaining parameters + $to = $node->booking_email; + $subject = t('!event Position Available', array('!event' => $event->booking_eventname)); + $params['subject'] = $subject; + $params['body'] = implode("\n\n", $contact_message); + //send the email + drupal_mail('booking', 'registration_mail', $to, $language, $params, $from); + drupal_mail('booking', 'registration_mail', 'it@coadcorp.com', $language, $params, $from); +} +*/ + diff --git a/booking.events.inc b/booking.events.inc new file mode 100644 index 0000000..d850f73 --- /dev/null +++ b/booking.events.inc @@ -0,0 +1,293 @@ +!link

", + array ('!link' => l('Add New Event', 'admin/config/booking/events/create'))); + + $header = array ( + 'booking_eventid' => t('Event ID'), + 'booking_eventname' => t('Event Name'), + 'booking_event_active' => t('Event currently active'), + 'booking_event_start' => t('Event Start Date'), + 'booking_event_end' => t('Event End Date'), + 'booking_register_open' => t('Registrations open'), + 'booking_register_close' => t('Registrations close'), + 'booking_earlybird_close' => t('Early discounted rate closes'), + 'booking_edit' => t('Edit event'), + ); + + $result = db_query("SELECT * from {booking_event}"); + + foreach($result as $data) + { + $options[$data->eid] = array + ( + 'booking_eventid' => $data->eid, + 'booking_eventname' => $data->booking_eventname, + 'booking_event_active' => $data->booking_event_active == 1 ? 'Yes' : 'No', + 'booking_event_start' => date("Y-m-d H:i", $data->booking_event_start), + 'booking_event_end' => date("Y-m-d H:i", $data->booking_event_end), + 'booking_register_open' => date("Y-m-d H:i", $data->booking_register_open), + 'booking_register_close' => date("Y-m-d H:i", $data->booking_register_close), + 'booking_earlybird_close' => date("Y-m-d H:i", $data->booking_earlybird_close), + 'booking_edit' => l('Edit', t('admin/config/booking/events/!eid/edit', array('!eid' => $data->eid))), + ); + } + + $form['table'] = array ( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + '#multiple' => false, + ); + + $form['submit_active'] = array + ( + '#type' => 'submit', + '#value' => t('Set Active'), + ); + + //watchdog('booking', 'Setting button form: @info', array ('@info' => var_export($form, TRUE))); + + return array ( + /* + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + //'#theme' => 'system_settings_form', + ), + */ + 'form' => $form, + ); +} + + +function booking_event_admin_submit($form, &$form_state) { + + $selected_event = $form_state['values']['table']; //$values['booking_price_active']; + //watchdog('booking', 'Formstate when setting event active: @info', array ('@info' => var_export($form_state['values'], TRUE))); + //watchdog('booking', 'Checkboxes when setting event active: @info', array ('@info' => var_export($selected_event, TRUE))); + + //First set all other event IDs to not active + db_update('booking_event') + ->fields(array ( + 'booking_event_active' => 0, + )) + ->condition('eid', $selected_event, '!=') + ->execute(); + + //then set our target event id to be active + db_update('booking_event') + ->fields(array ( + 'booking_event_active' => 1, + )) + ->condition('eid', $selected_event) + ->execute(); + + //update menus + menu_rebuild(); + +} + + +function booking_event_form($node, &$form_state, $create, $editid = 0) +{ + $form = array (); + $prefix = "

Add a new event to the bookings module.

"; + + if ($create == true) + { + $data = $node; + } + else + { + //verify that $editid is a number + if (! preg_match('/^[0-9]+$/', $editid)) { + drupal_set_message("Error: Invalid event ID supplied. Unable to update event information.", 'error', FALSE); + drupal_goto('admin/config/booking/events'); + return ""; + } + + $data = db_query("SELECT * FROM {booking_event} WHERE eid = :eventid", + array(':eventid' => $editid)) + ->fetchObject(); + $prefix = t("

Update the !event event details.

", array('!event' => $data->booking_eventname)); + //add this to the form in a hidden field so we can update the right event + $form['booking_eid'] = array ( + '#type' => 'hidden', + '#value' => $editid, + ); + } + + $form['booking_eventname'] = array ( + '#type' => 'textfield', + '#title' => t('The name of this event'), + '#size' => 60, + '#maxlength' => 150, + '#required' => TRUE, + '#default_value' => !empty($data->booking_eventname) ? $data->booking_eventname : '', + ); + + $form['booking_event_active'] = array( + '#type' => 'checkbox', + '#title' => t('Make this event active'), + '#default_value' => 1 + ); + + $form['booking_register_open'] = array( + '#type' => 'date_select', + '#title' => t('Date that registrations will open for this event'), + '#default_value' => empty($data->booking_register_open) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_register_open), + '#date_format' => 'd/m/Y H:i', + '#date_label_position' => 'within', + '#date_year_range' => '0:+5' + ); + + $form['booking_register_close'] = array( + '#type' => 'date_select', + '#title' => t('Date that registrations will close for this event'), + '#default_value' => empty($data->booking_register_close) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_register_close), + '#date_format' => 'd/m/Y H:i', + '#date_label_position' => 'within', + '#date_year_range' => '0:+5' + ); + + $form['booking_earlybird_close'] = array( + '#type' => 'date_select', + '#title' => t('Date that the early discounted rate will close for this event (if not applicable, set to registration close date)'), + '#default_value' => empty($data->booking_earlybird_close) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_earlybird_close), + '#date_format' => 'd/m/Y H:i', + '#date_label_position' => 'within', + '#date_year_range' => '0:+5' + ); + $form['booking_event_start'] = array( + '#type' => 'date_select', + '#title' => t('Date that this event will start'), + '#default_value' => empty($data->booking_event_start) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_event_start), + '#date_format' => 'd/m/Y H:i', + '#date_label_position' => 'within', + '#date_year_range' => '0:+5' + ); + $form['booking_event_end'] = array( + '#type' => 'date_select', + '#title' => t('Date that this event will conclude'), + '#default_value' => empty($data->booking_event_end) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_event_end), + '#date_format' => 'd/m/Y H:i', + '#date_label_position' => 'within', + '#date_year_range' => '0:+5' + ); + + if ($create == true) + { + $form['submit'] = array + ( + '#type' => 'submit', + '#value' => t('Create'), + ); + } else { + $form['Update'] = array + ( + '#type' => 'submit', + '#value' => t('Update'), + ); + $form['Delete'] = array + ( + '#type' => 'submit', + '#value' => t('Delete'), + ); + } + + return array ( + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + 'form' => $form, + ); +} + +function booking_event_form_submit($form, &$form_state) { + global $event; + $values = $form_state['input']; + + date_default_timezone_set('Australia/Sydney'); + $tz = new DateTimeZone('Australia/Sydney'); + + //watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE))); + + //check if this event is active. If it is, all other events should be made inactive + if ($values['booking_event_active'] == 1) + { + db_update('booking_event') + ->fields(array ( + 'booking_event_active' => 0, + )) + ->execute(); + } + + if ($form_state['values']['op'] == 'Create') + { + db_insert('booking_event') + ->fields(array( + 'booking_eventname' => $values['booking_eventname'], + 'booking_event_active' => $values['booking_event_active'] == 1 ? 1 : 0, + 'booking_register_open' => _datetime_array_to_ts($values['booking_register_open']), + 'booking_register_close' => _datetime_array_to_ts($values['booking_register_close']), + 'booking_earlybird_close' => _datetime_array_to_ts($values['booking_earlybird_close']), + 'booking_event_start' => _datetime_array_to_ts($values['booking_event_start']), + 'booking_event_end' => _datetime_array_to_ts($values['booking_event_end']), + + )) + ->execute(); + } + elseif ($form_state['values']['op'] == 'Delete') + { + //verify that booking_eid is a number + if (! preg_match('/^[0-9]+$/', $values['booking_eid'])) { + drupal_set_message("Error: Invalid event ID supplied. Unable to delete event entry.", 'error', FALSE); + return ""; + } + + $num_deleted = db_delete('booking_event') + ->condition('eid', $values['booking_eid']) + ->execute(); + + $message = t("Successfully deleted !num row(s), corresponding to event '!event'", + array('!num' => $num_deleted, '!event' => $values['booking_eventname'])); + drupal_set_message($message, $type = 'status'); + } + else + { + //verify that booking_eid is a number + if (! preg_match('/^[0-9]+$/', $values['booking_eid'])) { + drupal_set_message("Error: Invalid event ID supplied. Unable to update event entry.", 'error', FALSE); + return ""; + } + + //update the event + db_update('booking_event') + ->fields(array ( + 'booking_eventname' => $values['booking_eventname'], + 'booking_event_active' => $values['booking_event_active'] == 1 ? 1 : 0, + 'booking_register_open' => _datetime_array_to_ts($values['booking_register_open']), + 'booking_register_close' => _datetime_array_to_ts($values['booking_register_close']), + 'booking_earlybird_close' => _datetime_array_to_ts($values['booking_earlybird_close']), + 'booking_event_start' => _datetime_array_to_ts($values['booking_event_start']), + 'booking_event_end' => _datetime_array_to_ts($values['booking_event_end']), + )) + ->condition('eid', $values['booking_eid']) + ->execute(); + } + + $form_state['redirect'] = array('admin/config/booking/events'); +} \ No newline at end of file diff --git a/booking.helper.inc b/booking.helper.inc new file mode 100644 index 0000000..4f0ea1c --- /dev/null +++ b/booking.helper.inc @@ -0,0 +1,798 @@ + var_export($matches, TRUE))); + if (! checkdnsrr($matches[2], "MX")) + return 0; + return 1; + } + //watchdog('booking', 'Email address checking doesnt match'); + return 0; +} + +/** + * Helper function to perform some validity checking of Medicare Numbers + * Based on http://dyball.wordpress.com/2007/12/05/validation-of-medicare-numbers/ + */ +function _valid_medicare_number($input) { + //strip any whitespace + $medicare = preg_replace( '/\s+/', '', $input ); + if (is_numeric($medicare) && strlen($medicare) >= 9 && $medicare > 0) + { + $check_digit = $medicare[0] + (3 * $medicare[1]) + (7 * $medicare[2]) + (9 * $medicare[3]) + + $medicare[4] + (3 * $medicare[5]) + (7 * $medicare[6]) + (9 * $medicare[7]); + + if (($check_digit % 10) == $medicare[8]) + { + watchdog('booking', 'Medicare number (!mca) validates since check digit !check matches remainder from !remainder', + array('!mca' => $input, '!check' => $medicare[8], '!remainder' => $check_digit)); + return TRUE; + } + else + { + watchdog('booking', 'Medicare number (!mca) does not validate since check digit !check does not match remainder from !remainder', + array('!mca' => $input, '!check' => $medicare[8], '!remainder' => $check_digit)); + return FALSE; + } + } + else + { + watchdog('booking', 'Medicare number (!mca) does not validate since it is either non-numeric or too short', + array('!mca' => $input)); + return FALSE; + } +} +/** + * Helper function to perform some validity checking of a passport number + * Based on http://dyball.wordpress.com/2007/04/12/validation-of-passport-numbers/ + * @param $input string containing passport number to be verified + * @return boolean indicating if passport number is valid + */ +function _valid_passport_number($input) { + //strip whitespace + $passport = preg_replace( '/\s+/', '', $input ); + //check for a match + if (preg_match('/^[a-zA-Z]\d{7}$/', $input, $matches)) { + watchdog('booking', 'Passport number "!passnum" validates since it passed our regexp', + array('!passnum' => $input)); + return TRUE; + } + watchdog('booking', 'Passport number "!passnum" fails to validate', + array('!passnum' => $input)); + return FALSE; +} + +function _valid_phone_number($input) +{ + //strip any whitespace + $number = preg_replace( '/\s+/', '', $input ); + //strip any non-numeric characters + $number = preg_replace('/\D+/','', $number); + + if (is_numeric($number)) + return TRUE; + else + return FALSE; + + /* + if (preg_match('^(?:\+61|0061|0)(\d{3})\s*(\d{3})\s*(\d{3})$', $number, $matches)) + { + + } + */ +} + + +/** + * Helper function to check whether the number of registrations for the current event have reached their defined maximum size + */ +function _booking_check_bookings_full() +{ + global $event; + $waitinglist_query = db_query("SELECT count(*) as num_ppl FROM {booking_person} where booking_event_id = :eventid and booking_status = 1", + array(':eventid' => $event->eid)) + ->fetchObject(); + //check the number of people registered against the defined max + if ($waitinglist_query->num_ppl >= variable_get('booking_regn_limit', 350)) + { + watchdog('booking', 'There are !num people booked in, which is greater than or equal to the limit of !limit.', + array('!num' => $waitinglist_query->num_ppl, '!limit' => variable_get('booking_regn_limit', 350) )); + return true; + } + else + { + watchdog('booking', 'There are !num people booked in, which is less than the limit of !limit.', + array('!num' => $waitinglist_query->num_ppl, '!limit' => variable_get('booking_regn_limit', 350) )); + return false; + } +} + +/** + * Helper function to check who is the first person on the waiting list + */ +function _booking_get_waitinglist_top() +{ + global $event; + + $result = db_query('SELECT p.nid, p.booking_firstname, p.booking_lastname, pay.booking_payment_date + FROM {booking_person} p, {booking_payment} pay + WHERE booking_status = 2 and booking_event_id = :eid and p.nid = pay.booking_person_nid + ORDER BY pay.booking_payment_date + LIMIT 1', + array(':eid' => $event->eid)); + + foreach ($result as $person) + { + watchdog('booking', "First person on the waiting list: @info", array('@info' => var_export($person, TRUE))); + return $person->nid; + } + //in case there was no one on the waiting list + return -1; +} + +/** + * Helper function to update the status of a registration + */ +function _booking_change_status($nid, $status_id) +{ + db_update('booking_person') + ->fields(array( + 'booking_status' => $status_id, + )) + ->condition('nid', $nid) + ->execute(); +} + +function _datearray_to_ts($date) +{ + date_default_timezone_set(TIMEZONE); + $tz = new DateTimeZone(TIMEZONE); + + if (empty($date) || ($date['month'] == '' && $date['day'] == '' && $date['year'] == '')) + return 0; + else + watchdog('booking', "Date array to timestamp: @info", array('@info' => var_export($date, TRUE))); + + $gmt_ts = mktime(0, 0, 0, $date['month'], $date['day'], $date['year']); + $ts = new DateTime("@$gmt_ts"); + $ts->setTimezone($tz); + + return $ts->format("U"); +} + +function _datetime_array_to_ts($date) +{ + //watchdog('booking', 'Date-time Conversion: @info', array('@info' => var_export($date, TRUE))); + date_default_timezone_set(TIMEZONE); + $tz = new DateTimeZone(TIMEZONE); + + $gmt_ts = mktime($date['hour'], $date['minute'], 0, $date['month'], $date['day'], $date['year']); + $ts = new DateTime("@$gmt_ts"); + $ts->setTimezone($tz); + + return $ts->format("U"); +} + + +function _date_to_ts($date) { + $date_split = _split_date($date); + + date_default_timezone_set(TIMEZONE); + $tz = new DateTimeZone(TIMEZONE); + + if ($date_split[0] == '-1' ) + return 0; + else + { + $gmt_ts = mktime(0, 0, 0, $date_split[2], $date_split[3], $date_split[1]); + $ts = new DateTime("@$gmt_ts"); + $ts->setTimezone($tz); + + return $ts->format("U"); + } + //return mktime($date_split[5], $date_split[6], 0, $date_split[2], $date_split[3], $date_split[1]); +} + +function _datetime_to_ts($date) { + $date_split = _split_date($date); + + date_default_timezone_set(TIMEZONE); + $tz = new DateTimeZone(TIMEZONE); + + if ($date_split[0] == '-1' ) + return 0; + else + { + $gmt_ts = mktime($date_split[5], $date_split[6], 0, $date_split[2], $date_split[3], $date_split[1]); + $ts = new DateTime("@$gmt_ts"); + $ts->setTimezone($tz); + + return $ts->format("U"); + } + //return mktime($date_split[5], $date_split[6], 0, $date_split[2], $date_split[3], $date_split[1]); +} + +/** + * Function to split date into array + * + * @param $date in format YYYY-MM-DD + * @return array containing Year, Month, Day + */ +function _split_date($date) { + $pattern = '/^(\d{4})-(\d{2})-(\d{2})(\s(\d{2})\:(\d{2}))?/'; + if (preg_match($pattern, $date, $matches)) { + return $matches; + } else { + return array('-1'); + } +} + +/** + * Function to re-arrange date + * + * @param $date in format YYYY-MM-DD + * @return array containing Year, Month, Day + */ +function _arrange_date($date) { + $pattern = '/^(\d{4})-(\d{2})-(\d{2})/'; + if (preg_match($pattern, $date, $matches)) { + return $matches; + } else { + return array('-1'); + } +} + +/** + * Helper function to ensure timestamp is converted to correct local time + */ +function _booking_convert_ts($timestamp) +{ + //load the timestamp + date_default_timezone_set(TIMEZONE); + $tz = new DateTimeZone(TIMEZONE); + + $date = new DateTime("@$timestamp"); + $date->setTimezone($tz); + + return $date; +} + +function _date_range_to_string($date_start, $date_end) { + $start = _split_date($date_start); + $end = _split_date($date_end); + $final_string = ''; + + //check for correctly formatted dates + if ($start[0] == '-1' || $end[0] == '-1') { + //incorrect response + form_set_error('yc_date_endbeforestart', t('Invalid date format received from !date or !date_end.', array('!date' => $date_start, '!date_end' => $date_end))); + } else { + //start with the day field + //mktime uses format month, day, year + $end_string = strftime("%e", mktime(12, 0, 0, $end[2], $end[3], $end[1])); + $start_string = strftime("%e", mktime(12, 0, 0, $start[2], $start[3], $start[1])); + + //now include the month in the comparison. Compare including the year. + if (mktime(12, 0, 0, $end[2], 1, $end[1]) > mktime(12, 0, 0, $start[2], 1, $start[1])) { + //use the textual version to make things more readable + //strftime ( string $format [, int $timestamp = time() ] ) + //%B Full month name, based on the locale + $end_string .= ' ' . strftime("%B", mktime(12, 0, 0, $end[2], 1, $end[1])); + $start_string .= ' ' . strftime("%B", mktime(12, 0, 0, $start[2], 1, $start[1])); + } else { + $end_string .= ' ' . strftime("%B", mktime(12, 0, 0, $end[2], 1, $end[1])); + //no need to append anything to $start_string + } + + //create a timestamp based on 1 Jan that year to compare + if (mktime(12, 0, 0, 1, 1, $end[1]) > mktime(12, 0, 0, 1, 1, $start[1])) { + //create two seperate strings, one to hold the last part of the date range + //the other to hold the first part + $end_string .= ' ' . $end[1]; + $start_string .= ' ' . $start[1]; + } else { + $end_string .= ' ' . $end[1]; + //no need to append anything to $start_string + } + + //put both parts together + $final_string = $start_string . ' to ' . $end_string; + } + return $final_string; +} + + +//figure out if we're in the right time period for discounted registration rates +function _booking_is_earlybird() +{ + global $event; + + //figure out if we're in the earlybird rate section + //$early = db_query("SELECT booking_earlybird_close FROM {booking_event} where eid = :eid", array( + // ':eid' => $event->eid)) + // ->fetchObject(); + if ($event->booking_earlybird_close > time()) + return TRUE; + else + { + return FALSE; + } +} + +function _booking_datepaid_ts($nid) +{ + $query = db_query("SELECT * FROM {booking_payment} where booking_person_nid = :nid", array(':nid' => $nid)) + ->fetchObject(); + + if ($query) + return $query->booking_payment_date; + else + return 0; +} + +/** + * Helper function to return the amount for a booking deposit, if there is one + */ +function _booking_deposit_amount() +{ + global $event; + + $deposit = db_query("SELECT price.booking_price, price.booking_price_descrip " . + "FROM {booking_price} price WHERE booking_eventid = :eventid and booking_depositonly = 1 and booking_price_active = 1", + array(':eventid' => $event->eid)) + ->fetchObject(); + + if ($deposit) + { + //if we're using paypal, add the transaction fee + if (variable_get('booking_use_paypal', 0) == 1) + { + //add the 30 cent fixed cost + $amount_owing = $deposit->booking_price + 0.3; + //and the 2.4 percent transaction fee + $amount_owing = $amount_owing / (1 - 0.024); + } + else + { + $amount_owing = $deposit->booking_price; + } + //return the calculated amount rounded to two decimal places + return number_format($amount_owing, 2, '.', ''); + } + else + { + //there is no deposit amount + return 0; + } +} + +/** + * Calculate exactly how much a person has already paid + */ +function _booking_amount_paid($nid, $person = NULL) +{ + $amount_paid = 0; + + //fetch details about the person if we don't already have them + if ($person == NULL) + { + $person = db_query("SELECT price.booking_price, price.booking_late_price, person.booking_payment_id, " . + "person.booking_total_pay_reqd, person.booking_amount_paid, person.booking_partner_id " . + "FROM {booking_person} person, {booking_price} price " . + "WHERE person.nid = :nid " . + "AND person.booking_payment_id = price.pid", + array(':nid' => $nid)) + ->fetchObject(); + } + + //check for a spouse + if ($person->booking_partner_id > 0) + { + watchdog('booking', "Checking total paid for married person"); + + //if we're combining the payment for married couples + if (variable_get('booking_enable_combined_pricing', 0) == 1) + { + //check for payments in the paypal transaction table from either spouse + $query = db_query("SELECT booking_mc_gross, booking_mc_fee FROM booking_payment " . + "WHERE booking_person_nid = :nid OR booking_person_nid = :spousenid", + array(':nid' => $nid, 'spousenid' => $person->booking_partner_id)); + } + else { + //check for payments in the paypal transaction table from just this person + $query = db_query("SELECT booking_mc_gross, booking_mc_fee FROM booking_payment " . + "WHERE booking_person_nid = :nid", + array(':nid' => $nid)); + } + + //add up all the payments + foreach ($query as $payment) + $amount_paid += ($payment->booking_mc_gross - $payment->booking_mc_fee); + + watchdog('booking', "Total amount paid according to paypal payments table is " . $amount_paid); + + //if there were no results, $amount_paid will still be 0 + if ($amount_paid == 0) + { + //if we're combining the payment for married couples + if (variable_get('booking_enable_combined_pricing', 0) == 1) + { + $spouse = db_query("SELECT person.booking_amount_paid " . + "FROM {booking_person} person " . + "WHERE person.nid = :nid ", + array(':nid' => $person->booking_partner_id)) + ->fetchObject(); + $amount_paid = $person->booking_amount_paid + $spouse->booking_amount_paid; + watchdog('booking', "Total combined payments for couple based on totals in booking_person table is " . $amount_paid); + } + else + { + $amount_paid = $person->booking_amount_paid; + watchdog('booking', "Total amount paid for individual based on totals in booking_person table is " . $amount_paid); + } + + } + } + else + { + //Check if there are payment records in the paypal transaction table for this unmarried person + //if so, base their payments on the gross amount in there rather than what the person booking_person database says + $query = db_query("SELECT booking_mc_gross, booking_mc_fee FROM booking_payment " . + "WHERE booking_person_nid = :nid", + array(':nid' => $nid)); + foreach ($query as $payment) + $amount_paid += ($payment->booking_mc_gross - $payment->booking_mc_fee); + + //if there were no results, $amount_paid will still be 0 + if ($amount_paid == 0) + $amount_paid = $person->booking_amount_paid; + //in case there has been some manual adjustment + //elseif ($amount_paid < $person->booking_amount_paid) + // $amount_paid = $person->booking_amount_paid; + } + + watchdog('booking', "Total amount already paid for this registration " . $nid . " is " . $amount_paid); + + return $amount_paid; +} + +//calculate the amount outstanding for a person/married couple +function _booking_amount_owing($nid, $amount_paid = 0) +{ + //$amount_paid = 0; + $total_due = 0; + + //fetch details about the person + $person = db_query("SELECT price.booking_price, price.booking_late_price, person.booking_payment_id, " . + "person.booking_total_pay_reqd, person.booking_amount_paid, person.booking_partner_id " . + "FROM {booking_person} person, {booking_price} price " . + "WHERE person.nid = :nid " . + "AND person.booking_payment_id = price.pid", + array(':nid' => $nid)) + ->fetchObject(); + + //check for early bird rate or full rate + if (_booking_is_earlybird() == TRUE) + $total_due = $person->booking_total_pay_reqd; + else + $total_due = $person->booking_late_price; + + watchdog('booking', "Total amount due for this registration " . $nid . " is " . $total_due); + + //if we didn't get the amount paid as a command line parameter, check it now + if ($amount_paid == 0) + { + watchdog('booking', "Checking total amount already paid by " . $nid); + $amount_paid = _booking_amount_paid($nid, $person); + } + + /* + //check for a spouse + if ($person->booking_partner_id > 0) + { + watchdog('booking', "Checking outstanding balance for married person"); + + //if we're combining the payment for married couples + if (variable_get('booking_enable_combined_pricing', 0) == 1) + { + //check for payments in the paypal transaction table from either spouse + $query = db_query("SELECT booking_mc_gross FROM booking_payment " . + "WHERE booking_person_nid = :nid OR booking_person_nid = :spousenid", + array(':nid' => $nid, 'spousenid' => $person->booking_partner_id)); + } + else { + //check for payments in the paypal transaction table from just this person + $query = db_query("SELECT booking_mc_gross FROM booking_payment " . + "WHERE booking_person_nid = :nid", + array(':nid' => $nid)); + } + + //add up all the payments + foreach ($query as $payment) + $amount_paid += $payment->booking_mc_gross; + + watchdog('booking', "Total amount paid according to paypal payments table is " . $amount_paid); + + //if there were no results, $amount_paid will still be 0 + if ($amount_paid == 0) + { + //if we're combining the payment for married couples + if (variable_get('booking_enable_combined_pricing', 0) == 1) + { + $spouse = db_query("SELECT person.booking_amount_paid " . + "FROM {booking_person} person " . + "WHERE person.nid = :nid ", + array(':nid' => $person->booking_partner_id)) + ->fetchObject(); + $amount_paid = $person->booking_amount_paid + $spouse->booking_amount_paid; + watchdog('booking', "Total combined payments for couple based on totals in booking_person table is " . $amount_paid); + } + else + { + $amount_paid = $person->booking_amount_paid; + watchdog('booking', "Total amount paid for individual based on totals in booking_person table is " . $amount_paid); + } + + } + } + else + { + //Check if there are payment records in the paypal transaction table for this unmarried person + //if so, base their payments on the gross amount in there rather than what the person booking_person database says + $query = db_query("SELECT booking_mc_gross FROM booking_payment " . + "WHERE booking_person_nid = :nid", + array(':nid' => $nid)); + foreach ($query as $payment) + $amount_paid += $payment->booking_mc_gross; + + //if there were no results, $amount_paid will still be 0 + if ($amount_paid == 0) + $amount_paid = $person->booking_amount_paid; + //in case there has been some manual adjustment + elseif ($amount_paid < $person->booking_amount_paid) + $amount_paid = $person->booking_amount_paid; + } + + watchdog('booking', "Total amount already paid for this registration " . $nid . " is " . $amount_paid); + */ + + if ($amount_paid >= $total_due) + { + watchdog('booking', "This person doesn't owe any money: @info", array('@info' => var_export($person, TRUE))); + return 0; + } + + //if we're using paypal, add the transaction fee + if (variable_get('booking_use_paypal', 0) == 1) + { + //add the 30 cent fixed cost + $amount_owing = $total_due - $amount_paid + 0.3; + //and the 2.4 percent transaction fee + $amount_owing = $amount_owing / (1 - 0.024); + } + else + $amount_owing = $total_due - $amount_paid; + return number_format($amount_owing, 2, '.', ''); +} + +/** + * Helper function to generate paypal form for payments + */ +function _booking_paypal_form($person, $invoiceid, $amount_owing, $button_text) { + return drupal_render(drupal_get_form('_booking_paypal_form_builder', $person, $invoiceid, $amount_owing, $button_text)); +} + +/** + * Helper function to generate form elements for paypal form + */ +function _booking_paypal_form_builder($node, &$form_state, $person, $invoiceid, $amount_owing, $button_text) { + global $event; + $path = isset($_GET['q']) ? $_GET['q'] : ''; + + //paypal specific settings + $vars = array( + 'module' => 'Booking System', + 'type' => $event->booking_eventname, + //'custom' => $data, + 'item_name' => $event->booking_eventname . ' ' . $person->booking_price_descrip, + 'invoice' => $invoiceid, + 'no_shipping' => TRUE, + 'no_note' => TRUE, + 'currency_code' => 'AUD', + 'return' => url('bookingfinal', array('absolute' => TRUE)), + 'cancel_return' => url($path, array('absolute' => TRUE)), + 'rm' => '2', + 'amount' => $amount_owing, + 'last_name' => $person->booking_lastname, + 'first_name' => $person->booking_firstname, + 'cmd' => '_xclick', + 'notify_url' => url(BOOKING_PAYPAL_IPN_PATH, array('absolute' => TRUE)), + 'business' => variable_get('booking_paypal_account', '') + ); + + $form['#action'] = url(variable_get('booking_paypal_sandbox', 0) ? BOOKING_PAYPAL_SUBMIT_URL_SANDBOX : BOOKING_PAYPAL_SUBMIT_URL, array('absolute' => TRUE)); + + + foreach($vars as $name => $value) { + $form[$name] = array( + '#type' => 'hidden', + '#value' => $value, + ); + } + + $form['submit'] = array( + '#type' => 'button', + '#value' => t($button_text), + ); + + //watchdog('booking', 'Booking Balance payment: @info', array ('@info' => var_export($form, TRUE))); + return $form; +} + +/** + * Helper function to format registrations details for summary in the confirmation email + */ +function _booking_details_email_summary($node) { + + //query for payment type description + $payment_description_query = db_select('booking_price', 'p') + ->condition('p.pid', $node->booking_payment_id,'=') + ->fields('p', array('booking_price_descrip')) + ->execute() + ->fetchObject(); + + //watchdog('booking', "Payment description: @info", array('@info' => var_export($payment_description_query, TRUE))); + + $rows = array(); + $rows[] = t('Registration Reference Number: !id', array('!id' => $node->nid)); + $rows[] = t('Date/Time registered: !timestamp', array('!timestamp' => _booking_convert_ts($node->booking_timestamp)->format('j F, Y H:i'))); + $rows[] = t('Name: !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname)); + $rows[] = t('Gender: !gender', array('!gender' => $node->booking_gender == 'M' ? 'Male' : 'Female')); + $rows[] = t('Date of birth: !dob', array('!dob' => _booking_convert_ts($node->booking_dob)->format('d/m/Y'))); + + if (variable_get('booking_enable_passport', 1) == 1) + { + $rows[] = t('Passport Number: !value', array('!value' => $node->booking_passport_num)); + $rows[] = t('Passport Expiry: !timestamp', array('!timestamp' => _booking_convert_ts($node->booking_passport_expiry_date)->format('d/m/Y'))); + $rows[] = t('Passport Exact Issued Name: !value', array('!value' => $node->booking_passport_issue_name)); + $rows[] = t('Passport Issue Location: !value', array('!value' => $node->booking_passport_issue_location)); + } + + $rows[] = t('Email address: !email', array('!email' => $node->booking_email)); + $rows[] = t('Home Phone Number: !home', array('!home' => $node->booking_phone)); + $rows[] = t('Mobile Phone Number: !mob', array('!mob' => $node->booking_mobile)); + $rows[] = t("Postal Address:\n!street\n!suburb !state !code\n!country", + array('!street' => $node->booking_street, '!suburb' => $node->booking_suburb, + '!state' => $node->booking_state, '!code' => $node->booking_postcode, + '!country' => $node->booking_country)); + $rows[] = t('Ecclesia: !ecclesia', array('!ecclesia' => $node->booking_ecclesia)); + $rows[] = t('Baptised: !ans', array('!ans' => ($node->booking_baptised == 'Y' ? 'Yes' : 'No'))); + $rows[] = t('Married: !ans', array('!ans' => ($node->booking_married == 'Y' ? 'Yes' : 'No'))); + $rows[] = t("If married, attending partner's name: !name", array('!name' => $node->booking_partner_name)); + + if (variable_get('booking_enable_tshirts', 1) == 1) + $rows[] = t('Hoodie Size: !size', array('!size' => $node->booking_shirt_size)); + + $rows[] = t('Emergency Contact Name: !contact', array('!contact' => $node->booking_guardian_name)); + $rows[] = t('Emergency Contact Relationship: !relationship', array('!relationship' => $node->booking_guardian_type)); + $rows[] = t('Emergency Contact Phone: !phone', array('!phone' => $node->booking_guardian_phone)); + $rows[] = t('Emergency Contact Alternate Phone: !phone', array('!phone' => $node->booking_guardian_phone_alt)); + if (variable_get('booking_enable_medicare', 1) == 1) + $rows[] = t('Medicare Number: !medicare', array('!medicare' => $node->booking_medicare)); + + if (variable_get('booking_enable_roommate', 0) == 1) + { + $rows[] = t('Preferred room-mates: !room', array('!room' => $node->booking_room_mate1 . ' ' . $node->booking_room_mate2)); + } + + if (variable_get('booking_enable_helpareas', 1) == 1) + { + $help_areas = ''; + if ($node->booking_help_music) + $help_areas .= 'music: ' . $node->booking_help_music . ', '; + if ($node->booking_help_reading == 'Y') + $help_areas .= 'reading, '; + if ($node->booking_help_chairing == 'Y') + $help_areas .= 'chairing, '; + if ($node->booking_help_readgroup_lead == 'Y') + $help_areas .= 'reading group leading, '; + if ($node->booking_help_discussgroup_lead == 'Y') + $help_areas .= 'discussion group leading, '; + if ($node->booking_help_praying == 'Y') + $help_areas .= 'praying, '; + if ($node->booking_help_meditations == 'Y') + $help_areas .= 'meditations, '; + + $rows[] = t('Help areas: !help', array('!help' => $help_areas)); + } + + if (variable_get('booking_enable_skills', 1) == 1) + { + $skill_areas = ''; + if ($node->booking_skills_builder == 'Y') + $skill_areas .= 'builder, '; + if ($node->booking_skills_cooking == 'Y') + $skill_areas .= 'cook, '; + if ($node->booking_skills_childminding == 'Y') + $skill_areas .= 'child minding, '; + if ($node->booking_skills_language == 'Y') + $skill_areas .= 'speaks languages: ' . $node->booking_skills_language_details . ', '; + if ($node->booking_skills_other == 'Y') + $skill_areas .= 'other skills: ' . $node->booking_skills_other_details . ', '; + $rows[] = t('Mission related skills: !value', array('!value' => $skill_areas)); + $rows[] = t('Previous Mission Experience: !value', array('!value' => $node->booking_mission_experience_details)); + } + $rows[] = t('Special Dietary Requirements: !dietary', array('!dietary' => $node->booking_dietary)); + $rows[] = t('Special Medical Conditions: !medical', array('!medical' => $node->booking_medical_conditions)); + $rows[] = t('Gross Amount Paid: !payment', array('!payment' => $node->booking_amount_paid)); + $rows[] = t('Net Amount Due: !payment', array('!payment' => $node->booking_total_pay_reqd)); + $rows[] = t('Payment Type: !payment', array('!payment' => $payment_description_query->booking_price_descrip)); + + foreach ($rows as $key => $value) + $rows[$key] = wordwrap($value); + return implode("\n", $rows); +} + + +/** +* @brief Generates a Universally Unique IDentifier, version 4. +* +* This function generates a truly random UUID. The built in CakePHP String::uuid() function +* is not cryptographically secure. You should uses this function instead. +* +* @see http://tools.ietf.org/html/rfc4122#section-4.4 +* @see http://en.wikipedia.org/wiki/UUID +* @return string A UUID, made up of 32 hex digits and 4 hyphens. +*/ + function _booking_uuidSecure() { + + $pr_bits = null; + $fp = @fopen('/dev/urandom','rb'); + if ($fp !== false) { + $pr_bits .= @fread($fp, 16); + @fclose($fp); + } else { + // If /dev/urandom isn't available (eg: in non-unix systems), use mt_rand(). + $pr_bits = ""; + for($cnt=0; $cnt < 16; $cnt++){ + $pr_bits .= chr(mt_rand(0, 255)); + } + } + + $time_low = bin2hex(substr($pr_bits,0, 4)); + $time_mid = bin2hex(substr($pr_bits,4, 2)); + $time_hi_and_version = bin2hex(substr($pr_bits,6, 2)); + $clock_seq_hi_and_reserved = bin2hex(substr($pr_bits,8, 2)); + $node = bin2hex(substr($pr_bits,10, 6)); + + /** + * Set the four most significant bits (bits 12 through 15) of the + * time_hi_and_version field to the 4-bit version number from + * Section 4.1.3. + * @see http://tools.ietf.org/html/rfc4122#section-4.1.3 + */ + $time_hi_and_version = hexdec($time_hi_and_version); + $time_hi_and_version = $time_hi_and_version >> 4; + $time_hi_and_version = $time_hi_and_version | 0x4000; + + /** + * Set the two most significant bits (bits 6 and 7) of the + * clock_seq_hi_and_reserved to zero and one, respectively. + */ + $clock_seq_hi_and_reserved = hexdec($clock_seq_hi_and_reserved); + $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved >> 2; + $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved | 0x8000; + + return sprintf('%08s-%04s-%04x-%04x-%012s', + $time_low, $time_mid, $time_hi_and_version, $clock_seq_hi_and_reserved, $node); +} diff --git a/booking.import_data.inc b/booking.import_data.inc new file mode 100644 index 0000000..0904a9d --- /dev/null +++ b/booking.import_data.inc @@ -0,0 +1,161 @@ +Upload csv file containing data to import. Minimum fields present should be nid,booking_status,booking_total_pay_reqd,booking_amount_paid with column names matching that exactly (case sensitive).

"; + + $form = array(); + + $form['file'] = array( + '#type' => 'file', + '#title' => t('CSV data'), + '#description' => t('Upload CSV data to be processed'), + ); + + $form['submit'] = array ( + '#type' => 'submit', + '#value' => t('Submit'), + ); + + return array ( + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + 'form' => $form, + ); +} + +function booking_import_data_admin_validate($form, &$form_state) { + $file = file_save_upload('file', array( + 'file_validate_extensions' => array('txt csv'), // Validate extensions. + )); + // If the file passed validation: + if ($file) { + // Move the file, into the Drupal file system + if ($file = file_move($file, 'public://', FILE_EXISTS_REPLACE )) { + // Save the file for use in the submit handler. + $form_state['storage']['file'] = $file; + } + else { + form_set_error('file', t('Failed to write the uploaded file to the site\'s file folder.')); + } + } + else { + form_set_error('file', t('No file was uploaded.')); + } +} + +function booking_import_data_admin_submit($form, &$form_state) +{ + global $event; + $array = array(); + $expected_fields = array('nid', 'booking_amount_paid', 'booking_total_pay_reqd', 'booking_status'); + $error = false; + $update_counter = 0; + $delimiter = ","; + + //get the file name from temporary storage field + $file = $form_state['storage']['file']; + // We are done with the file, remove it from storage. + unset($form_state['storage']['file']); + + drupal_set_message(t('Input file uploaded successfully, filename: "@filename"', array('@filename' => $file->filename))); + $filename = drupal_realpath($file->uri); + + //convert csv to associative array + //based on http://stackoverflow.com/questions/4801895/csv-to-associative-array + if( ($handle = fopen( $filename, "r")) !== FALSE) { + $rowCounter = 0; + while (($rowData = fgetcsv($handle, 0, $delimiter)) !== FALSE) { + if( 0 === $rowCounter) { + $headerRecord = $rowData; + } else { + foreach( $rowData as $key => $value) { + $array[ $rowCounter - 1][ $headerRecord[ $key] ] = $value; + } + } + $rowCounter++; + } + fclose($handle); + } + else //unable to open file + { + drupal_set_message("Error: Unable to open input file " . $filename, 'error', FALSE); + return; + } + + //process the input data + foreach ($array as $record) + { + //watchdog('booking', 'Processing user record: @info', array ('@info' => $record['nid'])); + $update_counter++; + + //do some error checking + foreach($expected_fields as $field) + { +/* + if (! isset($record[$field])) + watchdog('booking', 'Non-set field !field: !info', array ('!field' => $field, '!info' => var_export($record, TRUE))); + if ($record[$field] == '') + watchdog('booking', 'Blank field !field: !info', array ('!field' => $field, '!info' => var_export($record, TRUE))); + */ + + if ( (! isset($record[$field])) || $record[$field] == '' ) + { + drupal_set_message("Error: Unable to locate expected field '$field' in input file for record number $update_counter.", 'error', FALSE); + //watchdog('booking', 'Processing user record: @info', array ('@info' => $record['nid'])); + //$error = true; + //skip to the next record + continue 2; + } + } + + drupal_set_message(t('Setting payment for id !nid to $!price of total required $!total and status to !status', + array('!nid' => $record['nid'], + '!price' => $record['booking_amount_paid'], + '!total' => $record['booking_total_pay_reqd'], + '!status' => _booking_status_lookup($record['booking_status'])) + )); + + watchdog('booking', 'Setting payment for regn id !nid to $!price and status to !status', + array('!nid' => $record['nid'], '!price' => $record['booking_amount_paid'], '!status' => _booking_status_lookup($record['booking_status']))); + + db_update('booking_person') + ->fields(array( + 'booking_amount_paid' => $record['booking_amount_paid'], + 'booking_total_pay_reqd' => $record['booking_total_pay_reqd'], + 'booking_status' => _booking_status_lookup($record['booking_status']), + )) + ->condition('nid', $record['nid']) + ->execute(); + + } + + //delete the uploaded file + file_delete($file); + + //let the user know we finished + drupal_set_message(t("Finished processing @count records from input file \"@filename\"", + array('@count' => $update_counter, '@filename' => $file->filename))); + +/* + // Make the storage of the file permanent + $file->status = FILE_STATUS_PERMANENT; + // Save file status. + file_save($file); + // Set a response to the user. + drupal_set_message(t('The form has been submitted and the image has been saved, filename: @filename.', array('@filename' => $file->filename))); +*/ + + +} \ No newline at end of file diff --git a/booking.info b/booking.info new file mode 100644 index 0000000..c91ca37 --- /dev/null +++ b/booking.info @@ -0,0 +1,9 @@ +; $Id$ +name = Booking System +description = "A module which provides a booking system for event registration." +package = Booking System +dependencies[] = date +dependencies[] = token +version = 0.2 +configure = admin/config/booking +core = 7.x \ No newline at end of file diff --git a/booking.install b/booking.install new file mode 100644 index 0000000..2e02960 --- /dev/null +++ b/booking.install @@ -0,0 +1,363 @@ + 'numeric', 'not null' => FALSE, 'default' => 0, 'precision' => '5', 'scale' => '2'); + db_add_field( 'booking_price', 'booking_late_price', $spec); +} + +function booking_update_7101() { + $spec = array('type' => 'varchar', 'length' => '50', 'not null' => FALSE); + db_add_field( 'booking_price', 'booking_late_buttonid', $spec); +} + +function booking_update_7102() { + $spec = array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'); + db_add_field( 'booking_person', 'booking_deposit_timestamp', $spec); +} + +function booking_update_7103() { + $spec = array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'); + db_add_field( 'booking_event', 'booking_event_start', $spec); + $spec = array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'); + db_add_field( 'booking_event', 'booking_event_end', $spec); +} + +function booking_update_7104() { + $spec = array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'); + db_change_field('booking_person', 'booking_deposit_timestamp', 'booking_deposit_timestamp', $spec); +} + +function booking_update_7105() { + //remove no longer used earlybird rate flag, replaced by regular and late prices + db_drop_field('booking_price', 'booking_earlybird_rate'); +} + +function booking_update_7106() { + //add passport details + $spec = array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'); + db_add_field( 'booking_person', 'booking_passport_issue_date', $spec); + db_add_field( 'booking_person', 'booking_passport_expiry_date', $spec); + $spec = array('type' => 'varchar', 'length' => '50', 'not null' => FALSE); + db_add_field( 'booking_person', 'booking_passport_num', $spec); + //add mission area experience details + $spec = array('type' => 'varchar', 'length' => '1', 'not null' => FALSE); + db_add_field( 'booking_person', 'booking_has_mission_experience', $spec); + $spec = array('type' => 'varchar', 'length' => '200', 'not null' => FALSE); + db_add_field( 'booking_person', 'booking_mission_experience_details', $spec); +} + +function booking_update_7107() { + $spec = array('type' => 'varchar', 'length' => '500', 'not null' => FALSE); + db_change_field('booking_person', 'booking_mission_experience_details', 'booking_mission_experience_details', $spec); +} + +/** +* Add special skills section, update passport info +*/ +function booking_update_7108() { + //passport updates + $spec = array('type' => 'varchar', 'length' => '200', 'not null' => FALSE); + db_add_field( 'booking_person', 'booking_passport_issue_location', $spec); + db_add_field( 'booking_person', 'booking_passport_issue_name', $spec); + db_drop_field('booking_price', 'booking_passport_issue_date'); + //skills type flags + $spec_flag = array('type' => 'varchar', 'length' => '1', 'not null' => FALSE); + db_add_field( 'booking_person', 'booking_skills_builder', $spec_flag); + db_add_field( 'booking_person', 'booking_skills_cooking', $spec_flag); + db_add_field( 'booking_person', 'booking_skills_childminding', $spec_flag); + db_add_field( 'booking_person', 'booking_skills_language', $spec_flag); + db_add_field( 'booking_person', 'booking_skills_language_details', $spec); + db_add_field( 'booking_person', 'booking_skills_other', $spec_flag); + db_add_field( 'booking_person', 'booking_skills_other_details', $spec); + +} +/** +* Make varchar fields bigger +*/ +function booking_update_7109() { + $spec = array('type' => 'varchar', 'length' => '500', 'not null' => FALSE); + db_change_field('booking_person', 'booking_passport_issue_location', 'booking_passport_issue_location', $spec); + db_change_field('booking_person', 'booking_skills_language_details', 'booking_skills_language_details', $spec); + db_change_field('booking_person', 'booking_skills_other_details', 'booking_skills_other_details', $spec); +} + +/** +* Add event ID field to the payments table +*/ +function booking_update_7201() { + //$spec = array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'); + //db_add_field( 'booking_payment', 'booking_eventid', $spec); +} + +/** +* Add table for variety sessions +*/ +function booking_update_7202() { + $booking_variety_options = array( + 'fields' => array( + 'vid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_status' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE), + 'booking_variety_timeslot_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_descrip' => array('type' => 'varchar', 'length' => '500', 'not null' => TRUE), + 'booking_variety_maxsize' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_regncount' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + ), + 'primary key' => array('vid'), + ); + $booking_variety_times = array( + 'fields' => array( + 'tid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_status' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE), + 'booking_variety_time_descrip' => array('type' => 'varchar', 'length' => '500', 'not null' => TRUE), + 'booking_variety_start' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + 'booking_variety_end' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + ), + 'primary key' => array('tid'), + ); + + $booking_variety_regn = array( + 'fields' => array( + 'rid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_node_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + ), + 'primary key' => array('rid'), + ); + + + db_create_table('booking_variety_options', $booking_variety_options); + db_create_table('booking_variety_times', $booking_variety_times); + db_create_table('booking_variety_regn', $booking_variety_regn); + + //TODO: create tables for variety session timeslots and variety session registrations (map user to variety session id) + //admin forms to create timeslots, then add variety sessions to each timeslot + //user form to register for a given variety session +} + +/** + * Implementation of hook_install(). + */ +function booking_install() { + // Create tables. + //not needed for d7 + //drupal_install_schema('booking'); + + //TODO: Don't hard code this + //define('EVENTID', 1); + +/* +limit bookings to 350 + + +non workers $260 +workers $300 +married $540 + +full payment after 28 feb +$380 pp +*/ + + + +$result = db_insert('booking_price') + ->fields(array( + 'booking_eventid' => 1, + 'booking_price' => '50.00', + 'booking_price_descrip' => 'Deposit', + 'booking_buttonid' => '9LMSELBEEL5W2', + 'booking_price_active' => 1, + 'booking_depositonly' => 1, + )) + ->execute(); + +$result = db_insert('booking_price') + ->fields(array( + 'booking_eventid' => 1, + 'booking_price' => '300.00', + 'booking_price_descrip' => 'Worker', + 'booking_buttonid' => 'R7PR6FASQMHSS', + 'booking_price_active' => 1, + 'booking_depositonly' => 0, + )) + ->execute(); + +$result = db_insert('booking_price') + ->fields(array( + 'booking_eventid' => 1, + 'booking_price' => '260.00', + 'booking_price_descrip' => 'Non-Worker', + 'booking_buttonid' => 'R2CF3G96WX4XA', + 'booking_price_active' => 1, + 'booking_depositonly' => 0, + )) + ->execute(); + +$result = db_insert('booking_price') + ->fields(array( + 'booking_eventid' => 1, + 'booking_price' => '540.00', + 'booking_price_descrip' => 'Married Couple', + 'booking_buttonid' => 'QST6YCMZFYEN4', + 'booking_price_active' => 1, + 'booking_depositonly' => 0, + )) + ->execute(); + +$result = db_insert('booking_event') + ->fields(array( + 'booking_eventname' => 'Study Weekend 2012', + 'booking_event_active' => 1, + 'booking_register_open' => 1312207199, + 'booking_register_close' => 1340459999, + 'booking_earlybird_close' => 1328018399, + )) + ->execute(); + + //earlybird close is 31st Jan 2012 at 13:59:59 UTC + + +} + +/** + * Implementation of hook_uninstall() + */ +function booking_uninstall() { + // Remove tables. + drupal_uninstall_schema('booking'); +} + + +/** + * Implementation of hook_schema(). + */ +function booking_schema() { + $schema['booking_person'] = array( + 'fields' => array( + //identifiers + 'nid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_event_id' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE), + 'booking_tempid' => array('type' => 'varchar', 'length' => '40', 'not null' => FALSE), + 'booking_timestamp' => array('type' => 'int', 'not null' => TRUE, 'disp-width' => '11'), + 'booking_status' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE), + 'booking_barcode' => array('type' => 'varchar', 'length' => '8', 'not null' => FALSE), + 'booking_firstname' => array('type' => 'varchar', 'length' => '50', 'not null' => TRUE), + 'booking_lastname' => array('type' => 'varchar', 'length' => '50', 'not null' => TRUE), + 'booking_gender' => array('type' => 'varchar', 'length' => '1', 'not null' => TRUE), + 'booking_dob' => array('type' => 'int', 'not null' => TRUE, 'disp-width' => '11'), + 'booking_shirt_size' => array('type' => 'varchar', 'length' => '20', 'not null' => FALSE), + //address details + 'booking_street' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE), + 'booking_suburb' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE), + 'booking_postcode' => array('type' => 'varchar', 'length' => '8', 'not null' => FALSE), + 'booking_state' => array('type' => 'varchar', 'length' => '30', 'not null' => FALSE), + 'booking_country' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE), + 'booking_phone' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_mobile' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_email' => array('type' => 'varchar', 'length' => '200', 'not null' => TRUE), + 'booking_ecclesia' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE), + 'booking_baptised' => array('type' => 'varchar', 'length' => '1', 'not null' => TRUE), + //relationships + 'booking_married' => array('type' => 'varchar', 'length' => '1', 'not null' => TRUE), + 'booking_partner_name' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE), + 'booking_partner_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10'), + 'booking_room_mate1' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + 'booking_room_mate2' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + //helping areas + 'booking_readinggroup' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + 'booking_help_music' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + 'booking_help_reading' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_help_chairing' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_help_discussgroup_lead' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_help_readgroup_lead' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_help_praying' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_help_meditations' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + //emergency contact info + 'booking_guardian_name' => array('type' => 'varchar', 'length' => '100', 'not null' => TRUE), + 'booking_guardian_type' => array('type' => 'varchar', 'length' => '100', 'not null' => TRUE), + 'booking_guardian_phone' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_guardian_phone_alt' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_medicare' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + //'booking_medicare_expiry' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + //'booking_medicare_linenum' => array('type' => 'varchar', 'length' => '2', 'not null' => FALSE), + 'booking_lifesaver' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_firstaid' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_nurse' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_doctor' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE), + 'booking_dietary' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + 'booking_medical_conditions' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + //payment info + 'booking_payment_id' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE), + //'booking_payment_method' => array('type' => 'varchar', 'length' => '100', 'not null' => TRUE), + 'booking_total_pay_reqd' => array('type' => 'numeric', 'not null' => FALSE, 'default' => 0, 'precision' => '5', 'scale' => '2'), + 'booking_amount_paid' => array('type' => 'numeric', 'not null' => FALSE, 'default' => 0, 'precision' => '5', 'scale' => '2'), + 'booking_deposit_timestamp' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + ), + 'primary key' => array('nid'), + ); + $schema['booking_event'] = array( + 'fields' => array( + 'eid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_eventname' => array('type' => 'varchar', 'length' => '200', 'not null' => TRUE), + 'booking_event_active' => array('type' => 'varchar', 'length' => '1', 'default' => 0, 'not null' => TRUE), + 'booking_register_open' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + 'booking_register_close' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + 'booking_earlybird_close' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + 'booking_event_start' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + 'booking_event_end' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + ), + 'primary key' => array('eid'), + ); + $schema['booking_price'] = array( + 'fields' => array( + 'pid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_price' => array('type' => 'numeric', 'not null' => FALSE, 'default' => 0, 'precision' => '5', 'scale' => '2'), + 'booking_late_price' => array('type' => 'numeric', 'not null' => FALSE, 'default' => 0, 'precision' => '5', 'scale' => '2'), + 'booking_price_descrip' => array('type' => 'varchar', 'length' => '100', 'not null' => TRUE), + 'booking_buttonid' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_late_buttonid' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_price_active' => array('type' => 'varchar', 'length' => '1', 'default' => 0, 'not null' => TRUE), + 'booking_earlybird_rate' => array('type' => 'varchar', 'length' => '1', 'default' => 0, 'not null' => TRUE), + 'booking_depositonly' => array('type' => 'varchar', 'length' => '1', 'default' => 0, 'not null' => TRUE), + ), + 'primary key' => array('pid'), + ); + $schema['booking_payment'] = array( + 'fields' => array( + 'payid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_person_nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_mc_gross' => array('type' => 'numeric', 'not null' => FALSE, 'default' => 0, 'precision' => '5', 'scale' => '2'), + 'booking_mc_currency' => array('type' => 'varchar', 'length' => '10', 'not null' => FALSE), + 'booking_mc_fee' => array('type' => 'numeric', 'not null' => FALSE, 'default' => 0, 'precision' => '5', 'scale' => '2'), + 'booking_quantity' => array('type' => 'int', 'length' => 11, 'not null' => FALSE, 'default' => 0), + 'booking_invoice' => array('type' => 'varchar', 'length' => '150', 'not null' => FALSE), + 'booking_payer_id' => array('type' => 'varchar', 'length' => '150', 'not null' => FALSE), + 'booking_payment_date' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'), + 'booking_payment_status' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_first_name' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE), + 'booking_last_name' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE), + 'booking_buyer_email' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + 'booking_payer_status' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE), + 'booking_item_name' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE), + 'booking_ipn_track_id' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE)), + 'primary key' => array('payid'), + ); + + $schema['booking_variety_options'] = array( + 'fields' => array( + 'vid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_status' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE), + 'booking_variety_timeslot_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_descrip' => array('type' => 'varchar', 'length' => '500', 'not null' => TRUE), + 'booking_variety_maxsize' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + 'booking_variety_regncount' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), + ), + 'primary key' => array('vid'), + ); + + return $schema; +} diff --git a/booking.manual_payment.inc b/booking.manual_payment.inc new file mode 100644 index 0000000..cf1e81c --- /dev/null +++ b/booking.manual_payment.inc @@ -0,0 +1,194 @@ + $event->eid,)); + + //empty payment option + $payment_type_options[0] = ''; + + foreach($result as $row) + { + $price = $early_price_applies == true ? $row->booking_price : $row->booking_late_price; + $payment_type_options[$row->pid] = $row->booking_price_descrip . ' ($' . $price . ')'; + } + + //any html to put at the start of the form + $prefix = t("

Manually enter payment details.
Note that this adds to the total amount paid already by each person.

"); + + $form['booking_earlybird'] = array ( + '#type' => 'hidden', + '#value' => $early_price_applies, + ); + $form['payment-type'] = array( + '#type' => 'select', + '#title' => t('Payment Type'), + '#required' => TRUE, + '#default_value' => '0', + '#options' => $payment_type_options, + ); + + $form['payment-custom-amount'] = array( + '#type' => 'textfield', + '#title' => t('Custom Amount Paid'), + '#maxlength' => 10, + '#field_prefix' => '$', + '#required' => FALSE, + '#default_value' => '0.00' + ); + + $header = array ( + 'booking_nid' => array('data' => t('Booking ID')), + 'booking_name' => array('data' => t('Name')), + 'booking_email' => array('data' => t('Email Address')), + 'amount_paid' => array('data' => t('Amount Paid To Date')), + 'amount_reqd' => array('data' => t('Gross Payment Required')), + 'booking_status' => t('Status'), + 'booking_fully_paid' => t('Fully Paid?'), + ); + + $result = db_query("SELECT * FROM {booking_person} WHERE booking_event_id = :eid", + array(':eid' => $event->eid)); + + foreach($result as $data) + { + $options[$data->nid] = array ( + 'booking_nid' => l(t('!id', array('!id' => $data->nid)), t('node/!id', array('!id' => $data->nid))), + 'booking_name' => $data->booking_firstname . " " . $data->booking_lastname, + 'booking_email' => $data->booking_email, + 'amount_paid' => $data->booking_amount_paid, + 'amount_reqd' => $data->booking_total_pay_reqd, + 'booking_status' => _booking_status_generate($data->booking_status), + 'booking_fully_paid' => $data->booking_amount_paid < $data->booking_total_pay_reqd ? 'No' : 'Yes', + ); + } + + $form['table'] = array ( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + ); + + $form['submit'] = array ( + '#type' => 'submit', + '#value' => t('Update'), + ); + + return array ( + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + 'form' => $form, + ); +} + +function booking_manual_payment_admin_submit($form, &$form_state) { + global $event; + $counter = 0; + $payment_date = REQUEST_TIME; + $checkboxes = $form_state['values']['table']; //$values['booking_price_active']; + //watchdog('booking', 'Formstate when setting buttons: @info', array ('@info' => var_export($form_state['values'], TRUE))); + //watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE))); + //watchdog('booking', 'Manual payment form contents: @info', array('@info' => var_export($form_state['values'], TRUE))); + + //check if there is a pre-defined payment type selected + if ($form_state['values']['payment-type'] != '' && $form_state['values']['payment-custom-amount'] == '0.00') + { + //look up the price relating to the price id selected + $price_query = db_query("SELECT price.booking_price, price.booking_late_price " . + "FROM {booking_price} price " . + "WHERE price.pid = :pid ", + array(':pid' => $form_state['values']['payment-type'])) + ->fetchObject(); + + $price = $form_state['values']['booking_earlybird'] == true ? $price_query->booking_price : $price_query->booking_late_price; + } + elseif ($form_state['values']['payment-custom-amount'] != '0.00' && is_numeric($form_state['values']['payment-custom-amount'])) + { + $price = $form_state['values']['payment-custom-amount']; + } + else + { + drupal_set_message("Error: Could not determine payment amount to update user(s).", 'error', FALSE); + return; + } + + foreach($checkboxes as $key => $value) + { + if (is_numeric($key) && $value != 0) + { + //check if they exist in the database first + $person = db_query("SELECT person.nid, person.booking_firstname, person.booking_lastname, person.booking_status, person.booking_partner_id, person.booking_amount_paid " . + "FROM {booking_person} person " . + "WHERE nid = :nid", + array(':nid' => $key)) + ->fetchObject(); + + if ($person) + { + //add this payment to their existing balance + $total_paid = $person->booking_amount_paid + $price; + + //determine what their booking status is now + if (_booking_check_bookings_full() == True || $person->booking_status == 2) + $status = 2; + else + $status = 1; + + watchdog('booking', 'Setting payment for regn id !nid to $!price and status to !status', array('!nid' => $key, '!price' => $price, '!status' => $status)); + + db_update('booking_person') + ->fields(array( + 'booking_amount_paid' => $total_paid, + 'booking_status' => $status, + )) + ->condition('nid', $key) + ->execute(); + + //Create a payment record entry for this update + $result = db_insert('booking_payment') + ->fields(array( + 'booking_person_nid' => $key, + 'booking_eventid' => $event->eid, + 'booking_mc_gross' => $price, + 'booking_mc_currency' => 'AUD', + 'booking_mc_fee' => '0.00', + 'booking_quantity' => 1, + 'booking_invoice' => 'ManualPayment', + 'booking_payer_id' => '', + 'booking_payment_date' => $payment_date, + 'booking_payment_status' => '', + 'booking_first_name' => $person->booking_firstname, + 'booking_last_name' => $person->booking_lastname, + 'booking_buyer_email' => '', + 'booking_payer_status' => '', + 'booking_item_name' => '', + 'booking_ipn_track_id' => '', + )) + ->execute(); + + $counter++; + } + else + drupal_set_message("Error: Unable to find person with registration ID " . $key, 'error', FALSE); + } + } + drupal_set_message("Added manual payments for $counter people of " . '$' . "$price.", 'status', FALSE); +} \ No newline at end of file diff --git a/booking.module b/booking.module new file mode 100644 index 0000000..be9bc6e --- /dev/null +++ b/booking.module @@ -0,0 +1,460 @@ +fetchObject(); + + //used for development only + //menu_rebuild(); +} + +/** + * Implementation of hook_permission(). + * D7 done. + */ +function booking_permission() { + return array( + 'access booking form' => array( + 'title' => t('Access the booking form'), + ), + 'access lists' => array( + 'title' => t('Access the coming and waiting lists'), + ), + 'access booking summary' => array( + 'title' => t('Access the summary of booking forms'), + ), + 'access reports' => array( + 'title' => t('Access booking reports'), + ), + 'create bookings' => array( + 'title' => t('Create a booking'), + ), + 'view bookings' => array( + 'title' => t('Access all bookings'), + ), + 'edit bookings' => array( + 'title' => t('Edit all bookings'), + ), + ); +} + +/** + * Implementation of hook_menu(). + */ +function booking_menu() { + global $event; + booking_init(); + //handle the case where the event hasn't been defined yet + $bookingTitle = !empty($event->booking_eventname) ? $event->booking_eventname : 'Event'; + + $items = array(); + + $items['admin/config/booking'] = array( + /* + 'title' => 'Booking module configuration', + 'description' => 'Configure the Booking module', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_admin'), + 'access arguments' => array('access administration pages'), + */ + + 'title' => 'Booking module configuration', + 'description' => 'Configure the Booking module', + 'position' => 'left', + 'weight' => -100, + 'page callback' => 'system_admin_menu_block_page', + 'access arguments' => array('administer site configuration'), + 'file' => 'system.admin.inc', + 'file path' => drupal_get_path('module', 'system'), + //'type' => MENU_DEFAULT_LOCAL_TASK, + + + ); + + $items['admin/config/booking/general'] = array( + + 'title' => 'Booking module general configuration', + 'description' => 'Configure general settings for Booking module', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_admin'), + 'access arguments' => array('administer site configuration'), + //'type' => MENU_DEFAULT_LOCAL_TASK, + //'position' => 'left', + 'weight' => -100, + ); + + + //http://www.akchauhan.com/create-drupal-form-using-theme_table-like-module-list-form/ + $items['admin/config/booking/text'] = array( + 'title' => 'Booking module text definitions', + 'description' => 'Configure text used in the CYC Booking module', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_tokens_admin'), + 'access arguments' => array('administer site configuration'), + //'type' => MENU_LOCAL_TASK, + ); + $items['admin/config/booking/prices'] = array( + 'title' => 'Booking module price settings', + 'description' => 'Configure prices for the Event Booking module', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_price_admin'), + 'access arguments' => array('administer site configuration'), + //'type' => MENU_LOCAL_TASK, + ); + + $items['admin/config/booking/events'] = array( + 'title' => 'Booking module event settings', + 'description' => 'Configure events for the Event Booking module', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_event_admin'), + 'access arguments' => array('administer site configuration'), + //'type' => MENU_LOCAL_TASK, + ); + $items['admin/config/booking/variety'] = array( + 'title' => 'Booking module variety sessions', + 'description' => 'Configure variety sessions for the Event Booking module', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_variety_admin'), + 'access arguments' => array('administer site configuration'), + //'type' => MENU_LOCAL_TASK, + ); + + $items['booking'] = array( + 'title' => $bookingTitle . ' Booking Form', + 'page callback' => 'booking_register_page', + 'access arguments' => array('access booking form'), + 'type' => MENU_NORMAL_ITEM, + ); + $items['confirm/%'] = array( + 'title' => 'Booking Payment', + 'page callback' => 'booking_confirm_page', + 'page arguments' => array(3), //include the temporary id + 'access arguments' => array('access booking form'), + 'type' => MENU_CALLBACK, + ); + + + $items['balance/%'] = array( + 'title' => 'Registration Final Payment', + 'page callback' => 'booking_balance_page', + 'page arguments' => array(3), //include the temporary id + 'access arguments' => array('access booking form'), + 'type' => MENU_CALLBACK, + ); + + //Various reports + $items['admin/booking/summary'] = array( + 'title' => 'Booking Summary', + 'description' => 'List people and their payments for the current event', + 'page callback' => 'booking_report_payments', + 'access arguments' => array('access reports'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items['admin/booking/paypal'] = array( + 'title' => 'Booking Paypal Summary', + 'description' => 'List paypal payments', + 'page callback' => 'booking_report_paypal_payments', + 'access arguments' => array('access reports'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items['admin/booking/manual-email'] = array( + 'title' => 'Manually Email People', + 'description' => 'Send manual email to registered people', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_manual_email'), + 'access arguments' => array('access administration pages'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items['admin/booking/manual-payments'] = array( + 'title' => 'Manual Payment Processing', + 'description' => 'Manually process peoples payments', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_manual_payment_admin'), + 'access arguments' => array('edit bookings'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items['admin/booking/csv'] = array( + 'title' => 'Booking Report', + 'description' => 'Download a csv of people registered for the current event', + 'page callback' => 'booking_csv_report', + 'access arguments' => array('access reports'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items['admin/booking/import-data'] = array( + 'title' => 'Booking Upload Data', + 'description' => 'Upload a csv of containing payment data', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_import_data_admin'), + 'access arguments' => array('edit bookings'), + 'type' => MENU_NORMAL_ITEM, + ); + + + $items['coming'] = array( + 'title' => "Who's Coming?", + 'page callback' => 'booking_coming_page', + 'access arguments' => array("access lists"), + 'type' => MENU_NORMAL_ITEM, + ); + + $items['waitinglist'] = array( + 'title' => "Who's on the waiting list?", + 'page callback' => 'booking_waitinglist_page', + 'access arguments' => array("access lists"), + 'type' => MENU_NORMAL_ITEM, + ); + + //The administration menu + + $items['admin/config/booking/prices/create'] = array( + 'title' => 'Add New Price Entry', + 'description' => 'Add priceentry for the Booking module', + 'page callback' => 'drupal_get_form', + //'page arguments' => array('booking_price_create'), + 'page arguments' => array('booking_price_form', true), + 'access arguments' => array('access administration pages'), + 'type' => MENU_LOCAL_ACTION, + ); + + $items['admin/config/booking/prices/%/edit'] = array( + 'title' => 'Edit Price', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_price_form', false, 4), + 'access arguments' => array('access administration pages'), + 'type' => MENU_CALLBACK, + ); + + $items['admin/config/booking/events/create'] = array( + 'title' => 'Add New Event', + 'description' => 'Add event for the Booking module', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_event_form', true), + 'access arguments' => array('access administration pages'), + 'type' => MENU_LOCAL_ACTION, + ); + + $items['admin/config/booking/events/%/edit'] = array( + 'title' => 'Edit Event', + //'page callback' => 'booking_event_create', + //'page arguments' => array(3), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_event_form', false, 4), + 'access arguments' => array('access administration pages'), + 'type' => MENU_CALLBACK, + ); + + $items['admin/config/booking/variety/create'] = array( + 'title' => 'Add New Variety Session', + 'description' => 'Add variety session for the Booking module', + 'page callback' => 'drupal_get_form', + //'page arguments' => array('booking_price_create'), + 'page arguments' => array('booking_variety_form', true), + 'access arguments' => array('access administration pages'), + 'type' => MENU_LOCAL_ACTION, + ); + + $items['admin/config/booking/variety/%/edit'] = array( + 'title' => 'Edit Variety Session', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('booking_variety_form', false, 4), + 'access arguments' => array('access administration pages'), + 'type' => MENU_CALLBACK, + ); + + + //the paypal IPN + $items[BOOKING_PAYPAL_IPN_PATH] = array( + 'type' => MENU_CALLBACK, + 'page callback' => 'booking_paypal_ipn', + 'access callback' => TRUE + ); + + return $items; + +} + +/** + * Describe the nodes we are going to define to model content specific to the booking module + * D7 done + */ +function booking_node_info() { + return array( + 'booking' => array( + 'name' => t('Registration'), + 'base' => 'booking', + 'description' => t('This node represents a booking into an event.'), + ) + ); +} + + +/** + * Implementation of access related hooks for booking_registration node type. + */ +function booking_node_access($node, $op, $account) { + $type = is_string($node) ? $node : $node->type; + + if ($type == 'booking' && in_array($type, node_permissions_get_configured_types())) { + //watchdog('booking', "Booking node_access processing user id '!account' performing operation !op for node type !type. @info", + // array('!account' => $account->uid, '!op' => $op, '!type' => $type, '@info' => var_export($account, TRUE))); + + if ($op == 'view') + { + //watchdog('booking', 'Booking node_access checking permissions for view operation.'); + if (user_access('view bookings', $account)) + return NODE_ACCESS_ALLOW; + } + elseif ($op == 'create') + { + //watchdog('booking', 'Booking node_access checking permissions for create operation.'); + if (user_access('create bookings', $account)) + return NODE_ACCESS_ALLOW; + //create is a special case, since typically anonymous users will be creating a booking node via the form anyway + //rather than logging a denied message for each registration, return denied here + else + return NODE_ACCESS_DENY; + } + elseif ($op == 'update' || $op == 'delete') + { + if (user_access('edit bookings', $account)) + return NODE_ACCESS_ALLOW; + } + + //no permission to view this information + //watchdog('booking', "Booking node_access denying uid !account performing operation !op. @info", + // array('!account' => $account->uid, '!op' => $op, '@info' => var_export($account, TRUE))); + watchdog('booking', "Booking node_access denying user id '!account' performing operation !op for node type !type. @info", + array('!account' => $account->uid, '!op' => $op, '!type' => $type, '@info' => var_export($account, TRUE))); + return NODE_ACCESS_DENY; + } + /* + else + { + watchdog('booking', "hook_node_access processing uid !account performing operation !op for node type !type. @info", + array('!account' => $account->uid, '!op' => $op, '!type' => $type, '@info' => var_export($account, TRUE))); + } + */ + + /* + if ($op == 'view') + return user_access('view all bookings', $account); + if ($op == 'create') + return user_access('create bookings', $account); + if ($op == 'update' || $op == 'delete') + return user_access('edit bookings', $account); + */ + +} + + +/** + * Implementation of hook_theme(). + */ +function booking_theme() { + return array( + 'booking_details' => array('arguments' => array('node' => NULL)), + //'booking_price_admin' => array('arguments' => array('form' => NULL)) + ); +} + +/** + * Implementation of hook_mail(). + */ +function booking_mail($key, &$message, $params) { + $message['subject'] = $params['subject']; + $message['body'][] = $params['body']; +} + +/** + * Registration node modification hooks for booking nodes. + */ +function booking_insert($node) { + //moved to booking.register.inc + watchdog('booking', 'Inserting person: @info', array('@info' => var_export($node, TRUE))); + _booking_insert($node); +} + +function booking_update($node) { + //moved to booking.register.inc + _booking_update($node); +} + +function booking_delete($node) { + //moved to booking.register.inc + _booking_delete($node); +} + +//Update node table specific attributes before hook_update is called +function booking_node_presave($node) { + global $event; + + if($node->type == 'booking') + { + $node->title = t('!event registration: !name', + array('!event' => $event->booking_eventname, '!name' => $node->booking_firstname . ' ' . $node->booking_lastname)); + //watchdog('booking', 'Presave of person: @info', array('@info' => var_export($node, TRUE))); + } +} diff --git a/booking.paypal.inc b/booking.paypal.inc new file mode 100644 index 0000000..d4b8e31 --- /dev/null +++ b/booking.paypal.inc @@ -0,0 +1,242 @@ + $value) { + $post .= $key. '='. urlencode($value). '&'; + } + $post .= 'cmd=_notify-validate'; + + return $post; +} + + +function _booking_paypal_ipn_verify($vars = array()) { + + if (variable_get('booking_paypal_sandbox', 0)) { + watchdog('booking', 'Setting IPN verify to true, running in sandbox mode'); + // PayPal sandbox requires login in order to even access, so for sandbox mode, simply return true. + return TRUE; + } + + $ch = curl_init(BOOKING_PAYPAL_SUBMIT_URL); + + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, _booking_paypal_post($vars)); + + ob_start(); + + if (curl_exec($ch)) { + $info = ob_get_contents(); + curl_close($ch); + ob_end_clean(); + + if (preg_match('/VERIFIED/i', $info)) { + watchdog('booking', 'Payment verification completed successfully: @info', array('@info' => $info)); + return TRUE; + } + else { + watchdog('booking', 'Payment verification not successful: @info', array('@info' => $info)); + return FALSE; + } + } + else { + watchdog('booking_paypal', 'Call to curl_exec() failed. url=@url vars=@vars', array( + '@vars' => print_r($vars, TRUE) + ), WATCHDOG_ERROR); + return FALSE; + } +} + + +/** + * Handles an incoming PayPal IPN. + */ +function booking_paypal_ipn() { + $ipn = $_POST; + + watchdog('booking', 'Payment notification received: @info', array('@info' => var_export($ipn, TRUE))); + + if(!_booking_paypal_ipn_verify($ipn)) + return; + + + /* + if ($ipn['payment_status'] != 'Pending' && variable_get('booking_paypal_sandbox', 0) == 1) { + watchdog('booking', 'Running in sandbox mode but type is not pending'); + return; + } + */ + if (empty($ipn['payment_status']) || ($ipn['payment_status'] != 'Completed' && variable_get('booking_paypal_sandbox', 0) == 0)) + return; + + + //Insert record into database and remove temporary booking id field from user + _booking_process_payment($ipn); + +} + +function _booking_process_payment($data) { + global $event; + $balance_payment = false; + + //extract the person node id from the invoice + $pos = strpos($data['invoice'], "_"); + if (($pos === false) || ($pos == 0)) + { + watchdog('booking', 'Unable to process payment with invalid invoice information: !id', array('!id' => $data['invoice']), WATCHDOG_ERROR); + return; + } + //get the part of the invoice up to the first underscore + $nid = substr($data['invoice'], 0, $pos); + //get the data between the first and second underscore + $eid = substr($data['invoice'], $pos + 1, strrpos($data['invoice'], "_") - $pos - 1); + + if (substr($eid,0,3) == "bal") + { + $balance_payment = true; + watchdog('booking', 'Balance payment for user with node id: !id', array('!id' => $nid)); + } + + //verify paypal hasn't already sent through a notification for this payment + $duplicate_check = db_query("SELECT payid, booking_person_nid FROM {booking_payment} where booking_ipn_track_id = :ipn_id ", + array(':ipn_id' => $data['ipn_track_id'])) + ->fetchObject(); + + if ($duplicate_check) + { + watchdog('booking', 'Detected duplicate paypal notifications for transaction id !id, registration id !nid', array('!id' => $data['ipn_track_id'], '!nid' => $nid), WATCHDOG_ERROR); + } + + watchdog('booking', 'Adding payment for user with node id: !id; event id: !eid', array('!id' => $nid, '!eid' => $eid)); + + $result = db_insert('booking_payment') + ->fields(array( + 'booking_person_nid' => $nid, + 'booking_eventid' => $event->eid, + 'booking_mc_gross' => $data['mc_gross'], + 'booking_mc_currency' => $data['mc_currency'], + 'booking_mc_fee' => $data['mc_fee'], + 'booking_quantity' => $data['quantity'], + 'booking_invoice' => $data['invoice'], + 'booking_payer_id' => $data['payer_id'], + 'booking_payment_date' => strtotime($data['payment_date']), + 'booking_payment_status' => $data['payment_status'], + 'booking_first_name' => $data['first_name'], + 'booking_last_name' => $data['last_name'], + 'booking_buyer_email' => $data['payer_email'], + 'booking_payer_status' => $data['payer_status'], + 'booking_item_name' => $data['item_name'], + 'booking_ipn_track_id' => $data['ipn_track_id'], + )) + ->execute(); + + //Get the person's info + //$payment = db_query("SELECT booking_amount_paid, booking_status, booking_total_pay_reqd, booking_partner_id FROM {booking_person} where nid = :nid", + // array(':nid' => $nid)) + // ->fetchObject(); + + $payment = db_select('booking_person', 'p') + ->condition('p.nid', $nid,'=') + ->fields('p', array('booking_amount_paid', 'booking_status', 'booking_total_pay_reqd', 'booking_partner_id')) + ->execute() + ->fetchObject(); + + if ($payment) + { + watchdog('booking', 'Found matching user with node id: !id; event id: !eid; existing payment !payment', array('!id' => $nid, '!eid' => $eid, + '!payment' => $payment->booking_amount_paid)); + //if successful, update their total payment amount + $total = $payment->booking_amount_paid + $data['mc_gross']; + + //only recalculate their booking status if this is the initial payment, not a payment of the outstanding balance + if ($balance_payment == FALSE) + { + watchdog('booking', 'Processing an initial payment. Booking status is currently ' . $payment->booking_status); + if (_booking_check_bookings_full() == True || $payment->booking_status == 2) + { + watchdog('booking', 'This registration belongs on the waiting list.'); + $status = 2; + } + else + { + watchdog('booking', 'This registration made it to the booked-in list.'); + $status = 1; + } + } + else //this is a balance payment + { + watchdog('booking', 'Processing a balance payment.'); + //if this is a payment of outstanding balance, keep the booking_status the same + $status = $payment->booking_status; + //$status = $payment->booking_status == 2 ? 2 : 1; + } + + //update the database for this person + db_update('booking_person') + ->fields(array( + 'booking_amount_paid' => $total, + 'booking_status' => $status, + )) + ->condition('nid', $nid) + ->execute(); + + //send a notification email + + //If there is no outstanding balance, send a payment complete email + if ($total >= $payment->booking_total_pay_reqd) + { + //this should always be a balance payment type email, since that tells the user that their payment is completed + _booking_registration_email($nid, TRUE); + + //if we are combining payments, and this person has a linked spouse + if ((variable_get('booking_enable_combined_pricing', 0) == 1) && ($payment->booking_partner_id > 0)) + { + //check spouse booking_status and payment info + $spouse = db_select('booking_person', 'p') + ->condition('p.nid', $payment->booking_partner_id,'=') + ->fields('p', array('booking_amount_paid', 'booking_status', 'booking_total_pay_reqd')) + ->execute() + ->fetchObject(); + + //update the spouse's status from "not paid" if required + $spouse_status = $spouse->booking_status == 0 ? 1 : $spouse_booking_status; + watchdog('booking', 'Setting status for spouse id !id to !new from !status', array('!id' => $payment->booking_partner_id, + '!new' => $spouse_status, '!status' => $spouse->booking_status)); + + //set the spouse's payment required to be zero or equal to their previous payment total + $spouse_new_amount_reqd = $spouse->booking_amount_paid > 0 ? $spouse->booking_amount_paid : 0; + watchdog('booking', 'Setting amount owing for spouse id !id to !new from !status', array('!id' => $spouse_new_amount_reqd, + '!new' => $spouse_status, '!status' => $spouse->booking_amount_paid)); + + //update the database for this person + db_update('booking_person') + ->fields(array( + 'booking_total_pay_reqd' => $spouse_new_amount_reqd, + 'booking_status' => $spouse_status, + )) + ->condition('nid', $payment->booking_partner_id) + ->execute(); + + //send an email + _booking_registration_email($payment->booking_partner_id, $balance_payment); + } //end spouse check + } + else //this person still has an outstanding balance so just send a confirmation email + { + _booking_registration_email($nid, $balance_payment); + } + } + else //couldn't find a matching nid for this invoice + { + watchdog('booking', "Unable to process payment for user with node id: '!id'", array('!id' => $nid), WATCHDOG_ERROR); + //db_query("UPDATE {booking_person} SET booking_tempid='' WHERE nid = %d", $nid); + } + + + +} \ No newline at end of file diff --git a/booking.prices.inc b/booking.prices.inc new file mode 100644 index 0000000..6922466 --- /dev/null +++ b/booking.prices.inc @@ -0,0 +1,282 @@ +!link

", + array ('!link' => l('Add New Price Entry', 'admin/config/booking/prices/create'))); + + $header = array ( + 'booking_price_active' => t('Active'), + 'booking_eventid' => t('Event ID'), + 'booking_price_descrip' => t('Description'), + 'booking_price' => t('Early-Bird Price'), + 'booking_buttonid' => t('Button ID'), + 'booking_late_price' => t('Late Booking Price'), + 'booking_late_buttonid' => t('Late Booking Button ID'), + 'booking_depositonly' => t('Deposit Only'), + 'booking_edit' => t('Edit Price'), + ); + + $result = db_query("SELECT pid, booking_eventid, booking_price, booking_late_price, booking_late_buttonid, booking_price_descrip, booking_buttonid, booking_price_active, " . + "booking_depositonly from {booking_price}"); + + foreach($result as $data) + { + $options[$data->pid] = array + ( + 'booking_price_active' => $data->booking_price_active == 1 ? 'Yes' : 'No', + 'booking_eventid' => $data->booking_eventid, + 'booking_price_descrip' => $data->booking_price_descrip, + 'booking_price' => $data->booking_price, + 'booking_buttonid' => $data->booking_buttonid, + 'booking_late_price' => $data->booking_late_price, + 'booking_late_buttonid' => $data->booking_late_buttonid, + 'booking_depositonly' => $data->booking_depositonly == 1 ? 'Yes' : 'No', + 'booking_edit' => l('Edit', t('admin/config/booking/prices/!pid/edit', array('!pid' => $data->pid))), + ); + } + + $form['table'] = array ( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + '#multiple' => true, + ); + + $form['submit_active'] = array + ( + '#type' => 'submit', + '#value' => t('Set Active'), + ); + + $form['submit_inactive'] = array + ( + '#type' => 'submit', + '#value' => t('Set Inactive'), + ); + + //watchdog('booking', 'Setting button form: @info', array ('@info' => var_export($form, TRUE))); + + return array ( + /* + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + */ + 'form' => $form, + ); +} + +function booking_price_admin_submit($form, &$form_state) { + + $checkboxes = $form_state['values']['table']; //$values['booking_price_active']; + //watchdog('booking', 'Formstate when setting buttons: @info', array ('@info' => var_export($form_state['values'], TRUE))); + + //watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE))); + + foreach($checkboxes as $key => $value) { + //only set the entries that are ticked + if ($value != 0) + { + if ($form_state['values']['op'] == 'Set Active') + $setting = 1; + else + $setting = 0; + + db_update('booking_price') + ->fields(array ( + 'booking_price_active' => $setting, + )) + ->condition('pid', $key) + ->execute(); + } + } +} + +function booking_price_form($node, &$form_state, $create, $editid = 0) +{ + $form = array (); + $prefix = "

Add a new payment option

"; + + if ($create == true) + { + $data = $node; + watchdog('booking', 'Creating new price entry: @info', array ('@info' => var_export($node, TRUE))); + } + else + { + //verify that $editid is a number + if (! preg_match('/^[0-9]+$/', $editid)) { + drupal_set_message("Error: Invalid price ID supplied. Unable to update price entry.", 'error', FALSE); + drupal_goto('admin/config/booking/prices'); + return ""; + } + + //$data = $form_state['input']; + $data = db_query("SELECT * FROM {booking_price} WHERE pid = :id", + array(':id' => $editid)) + ->fetchObject(); + $prefix = t("

Update the !event price details.

", array('!event' => $data->booking_price_descrip)); + //add this to the form in a hidden field so we can update the right price + $form['booking_pid'] = array ( + '#type' => 'hidden', + '#value' => $editid, + ); + watchdog('booking', 'Editing existing price entry: @info', array ('@info' => var_export($data, TRUE))); + } + + $form['booking_price_descrip'] = array ( + '#type' => 'textfield', + '#title' => t('Description of this price'), + '#size' => 60, + '#maxlength' => 150, + '#required' => TRUE, + '#default_value' => !empty($data->booking_price_descrip) ? $data->booking_price_descrip : '', + ); + $form['booking_price'] = array ( + '#type' => 'textfield', + '#title' => t('The earlybird price relating to this entry'), + '#field_prefix' => '$', + '#size' => 5, + '#maxlength' => 10, + '#required' => TRUE, + '#default_value' => !empty($data->booking_price) ? $data->booking_price : '', + ); + $form['booking_buttonid'] = array ( + '#type' => 'textfield', + '#title' => t('The PayPal button ID'), + '#size' => 20, + '#maxlength' => 20, + '#default_value' => !empty($data->booking_buttonid) ? $data->booking_buttonid : '', + ); + $form['booking_late_price'] = array ( + '#type' => 'textfield', + '#title' => t('The late booking price relating to this entry'), + '#field_prefix' => '$', + '#size' => 5, + '#maxlength' => 10, + '#required' => TRUE, + '#default_value' => !empty($data->booking_late_price) ? $data->booking_late_price : '', + ); + $form['booking_late_buttonid'] = array ( + '#type' => 'textfield', + '#title' => t('The PayPal button ID for late bookings'), + '#size' => 20, + '#maxlength' => 20, + '#default_value' => !empty($data->booking_late_buttonid) ? $data->booking_late_buttonid : '', + ); + + $form['booking_price_active'] = array( + '#type' => 'checkbox', + '#title' => t('Make this price active'), + '#default_value' => !empty($data->booking_price_active) ? $data->booking_price_active : '', + ); + + $form['booking_depositonly'] = array( + '#type' => 'checkbox', + '#title' => t('This is a deposit only price'), + '#default_value' => !empty($data->booking_depositonly) ? $data->booking_depositonly : 0, + ); + + if ($create == true) + { + $form['submit'] = array + ( + '#type' => 'submit', + '#value' => t('Create'), + ); + } else { + $form['Update'] = array + ( + '#type' => 'submit', + '#value' => t('Update'), + ); + $form['Delete'] = array + ( + '#type' => 'submit', + '#value' => t('Delete'), + ); + } + + return array ( + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + 'form' => $form, + ); +} + + +function booking_price_form_submit($form, &$form_state) { + global $event; + $values = $form_state['input']; + + //watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE))); + if ($form_state['values']['op'] == 'Create') + { + db_insert('booking_price') + ->fields(array( + 'booking_eventid' => $event->eid, + 'booking_price' => $values['booking_price'], + 'booking_late_price' => $values['booking_late_price'], + 'booking_price_descrip' => $values['booking_price_descrip'], + 'booking_buttonid' => $values['booking_buttonid'], + 'booking_price_active' => $values['booking_price_active'] == 1 ? 1 : 0, + 'booking_depositonly' => $values['booking_depositonly'] == 1 ? 1 : 0, + )) + ->execute(); + } + elseif ($form_state['values']['op'] == 'Delete') + { + //verify that booking_pid is a number + if (! preg_match('/^[0-9]+$/', $values['booking_pid'])) { + drupal_set_message("Error: Invalid price ID supplied. Unable to delete price entry.", 'error', FALSE); + return ""; + } + + //TODO: Confirmation + //return confirm_form($form, "Really delete price?", 'admin/config/booking/prices'); + + $num_deleted = db_delete('booking_price') + ->condition('pid', $values['booking_pid']) + ->execute(); + + $message = t("Successfully deleted !num row(s), corresponding to event price '!price'", + array('!num' => $num_deleted, '!price' => $values['booking_price_descrip'])); + drupal_set_message($message, $type = 'status'); + + } else { + + //verify that booking_pid is a number + if (! preg_match('/^[0-9]+$/', $values['booking_pid'])) { + drupal_set_message("Error: Invalid price ID supplied. Unable to update price entry.", 'error', FALSE); + return ""; + } + + //update the event + db_update('booking_price') + ->fields(array ( + 'booking_eventid' => $event->eid, + 'booking_price' => $values['booking_price'], + 'booking_late_price' => $values['booking_late_price'], + 'booking_price_descrip' => $values['booking_price_descrip'], + 'booking_buttonid' => $values['booking_buttonid'], + 'booking_price_active' => $values['booking_price_active'] == 1 ? 1 : 0, + 'booking_depositonly' => $values['booking_depositonly'] == 1 ? 1 : 0, + )) + ->condition('pid', $values['booking_pid']) + ->execute(); + } + + $form_state['redirect'] = array('admin/config/booking/prices'); +} diff --git a/booking.register.inc b/booking.register.inc new file mode 100644 index 0000000..e72164c --- /dev/null +++ b/booking.register.inc @@ -0,0 +1,1421 @@ + $event->eid))->fetchObject(); + + if ($booking_times->booking_register_open < time() && $booking_times->booking_register_close > time()) + { + //we are within the allowed timeframe for registrations + //check if this registration will be on the waiting list + if (_booking_check_bookings_full() == True) + { + $output = token_replace(variable_get('booking_registration_waiting_intro_text'), booking_define_tokens()); + } + else + { + //watchdog('booking', 'Booking registration form intro text: @info', array('@info' => var_export(variable_get('booking_registration_intro_text'), TRUE))); + $output = token_replace(variable_get('booking_registration_intro_text'), booking_define_tokens()); + } + $return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output)); + $return_array[] = array('form' => drupal_get_form('booking_form', true)); + } + elseif ($booking_times->booking_register_close < time()) + { + //too late to register + $output = token_replace(variable_get('default_into_regn_closed_text'), booking_define_tokens()); + $return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output)); + } + else + { + //too early to register + $output = token_replace(variable_get('default_into_regn_not_opened_text'), booking_define_tokens()); + $return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output)); + } + + return $return_array; +} + +function booking_form($node, &$form_state, $inserting = FALSE) { + + global $event; + $status_options = array(); + $payment_type_options = array(); + $partner_options = array(); + date_default_timezone_set(TIMEZONE); + + if (!empty($node)) + { + $data = $node; + //watchdog('booking', 'Booking registration form loading data from saved node: @info', array('@info' => var_export($node, TRUE))); + } + else + { + $data = $form_state['input']; + //watchdog('booking', 'Booking registration form loading data from form submission: @info', array('@info' => var_export($form_state, TRUE))); + } + + $emergency_contact_type_options = array( + 'parent' => 'Parent', + 'legal_guardian' => 'Legal Guardian', + 'relative' => 'Close Relative'); + + $status_options[0] = t('Not Paid'); + $status_options[1] = t('Booked In'); + $status_options[2] = t('Waiting List'); + $status_options[3] = t('No Longer Coming'); + + //figure out if we're in the earlybird rate section + $early = db_query("SELECT booking_earlybird_close FROM {booking_event} where eid = :eid", array( + ':eid' => $event->eid)) + ->fetchObject(); + if ($early->booking_earlybird_close > time()) + $select_early = 1; + else + { + $select_early = 0; + watchdog('booking', 'No longer accepting earlybird prices'); + } + + $result = db_query("SELECT pid, booking_price_descrip, booking_price, booking_late_price FROM {booking_price} where booking_eventid = :eid " . + "and booking_price_active=1 and booking_depositonly = 0", + array(':eid' => $event->eid,)); + + foreach($result as $row) + { + $price = $select_early == 1 ? $row->booking_price : $row->booking_late_price; + $payment_type_options[$row->pid] = $row->booking_price_descrip . ' ($' . $price . ')'; + } + + //form starts here + $form['your-details'] = array( + '#type' => 'fieldset', + '#title' => 'Personal details', + ); + + $form['your-details']['booking_firstname'] = array( + '#type' => 'textfield', + '#title' => t('First Name'), + '#maxlength' => 45, + '#required' => TRUE, + '#default_value' => !empty($data->booking_firstname) ? $data->booking_firstname : '' + ); + $form['your-details']['booking_lastname'] = array( + '#type' => 'textfield', + '#title' => t('Last Name'), + '#maxlength' => 45, + '#required' => TRUE, + '#default_value' => !empty($data->booking_lastname) ? $data->booking_lastname : '' + ); + $form['your-details']['booking_gender'] = array( + '#type' => 'select', + '#title' => t('Gender'), + '#required' => TRUE, + '#default_value' => variable_get('booking_gender', empty($data->booking_gender) ? 'M' : $data->booking_gender), + '#options' => array( + 'M' => 'Male', + 'F' => 'Female', + ), + ); + + //If we're loading this from an existing node, we need to convert the timestamp into the proper format + $form['your-details']['booking_dob'] = array( + '#type' => 'date_select', + '#title' => t('Date of Birth'), + '#default_value' => empty($data->booking_dob) ? '' : date("Y-m-d H:i:s", $data->booking_dob), + '#required' => TRUE, + '#date_format' => 'd/m/Y', + '#date_label_position' => 'within', + '#date_year_range' => '-50:-13' + ); + + $form['your-details']['booking_payment_id'] = array( + '#type' => 'select', + '#title' => t('Choose your payment type'), + '#default_value' => $inserting != TRUE ? $data->booking_payment_id : variable_get('booking_payment_id','worker'), + '#options' => $payment_type_options, + ); + + // The status field should not be visible unless this registration is being updated...i.e. not at actual registration time... + if ($inserting != TRUE) { + $form['your-details']['booking_status'] = array( + '#type' => 'radios', + '#title' => t('Registration Status'), + '#options' => $status_options, + '#default_value' => !empty($data->booking_status) ? $data->booking_status : '', + ); + } //end inserting check for booking status + + //tshirts + if (variable_get('booking_enable_tshirts', 0) == 1) + { + $form['your-details']['booking_shirt_size'] = array( + '#type' => 'select', + '#title' => t('Preferred hoodie size'), + '#required' => FALSE, + '#default_value' => variable_get('booking_shirt_size', empty($data->booking_shirt_size) ? '' : $data->booking_shirt_size), + '#options' => _get_tshirt_options(), + ); + } //end enable tshirts check + + $form['your-details']['booking_ecclesia'] = array( + '#type' => 'textfield', + '#title' => t('Ecclesia'), + '#maxlength' => 100, + '#required' => FALSE, + '#default_value' => !empty($data->booking_ecclesia) ? $data->booking_ecclesia : '' + ); + $form['your-details']['booking_baptised'] = array( + '#type' => 'checkbox', + '#title' => t('I am baptised'), + '#default_value' => (!empty($data->booking_baptised) && $data->booking_baptised == 'Y') ? 1 : 0 + ); + $form['your-details']['booking_married'] = array( + '#type' => 'checkbox', + '#title' => t('I am married'), + '#default_value' => (!empty($data->booking_married) && $data->booking_married == 'Y') ? 1 : 0 + ); + $form['your-details']['booking_partner_name'] = array( + '#type' => 'textfield', + '#title' => t('If your partner is coming to !event also, please enter their name here. They must register and pay seperately.', + array('!event' => $event->booking_eventname)), + '#maxlength' => 120, + '#required' => FALSE, + '#states' => array( + // Only show this field when the 'booking_married' checkbox is enabled. + 'visible' => array( + ':input[name="booking_married"]' => array('checked' => TRUE), + ), + ), + '#default_value' => !empty($data->booking_partner_name) ? $data->booking_partner_name : '' + ); + + if ($inserting == TRUE) + { + $form['your-details']['booking_partner_id'] = array( + '#type' => 'textfield', + '#title' => t('If your partner has already registered for !event, please enter their registration id (number only) from the email they were sent. Otherwise, leave blank', + array('!event' => $event->booking_eventname)), + '#maxlength' => 15, + '#size' => 4, + '#required' => FALSE, + '#states' => array( + // Only show this field when the 'booking_married' checkbox is enabled. + 'visible' => array( + ':input[name="booking_married"]' => array('checked' => TRUE), + ), + ), + '#default_value' => !empty($data->booking_partner_name) ? $data->booking_partner_name : '' + ); + } + else + { + //add the empty element first + $partner_options[0] = ''; + + //get a list of possible partners + $partners = db_query("SELECT nid, booking_firstname, booking_lastname, booking_partner_id FROM {booking_person} " . + "where booking_event_id = :eid and booking_married='Y' order by booking_lastname, booking_firstname", + array(':eid' => $event->eid)); + + //convert that into an array + foreach($partners as $row) + $partner_options[$row->nid] = $row->booking_firstname . ' ' . $row->booking_lastname; + //create a select field + $form['your-details']['booking_partner_id'] = array( + '#type' => 'select', + '#title' => t('Choose Spouse'), + '#default_value' => $data->booking_partner_id, + '#options' => $partner_options, + ); + } + + + //watchdog('booking', 'Booking registration form payment type: @info. Payment id: !id', + // array('@info' => $payment_type_options[$data->booking_payment_id], '!id' => $data->booking_payment_id )); + + //only show the booking agreement tickbox if the node is being created, since this value isn't stored anywhere + if ($inserting == TRUE) + { +/* + $form['your-details']['booking_regular_cyc'] = array + ( + '#type' => 'checkbox', + '#title' => t('Regularly Attend CYC '), + '#default_value' => empty($data->booking_agreement) ? 0 : $data->booking_agreement, + '#title' => t('I regularly attend CYC events/activities'), + ); */ + + $form['your-details']['booking_agreement'] = array + ( + '#type' => 'checkbox', + '#title' => t('Aims and Expectations'), + '#default_value' => empty($data->booking_agreement) ? 0 : $data->booking_agreement, + /* + '#states' => array( + // Only show this field when the checkbox is unchecked. + 'visible' => array( + ':input[name="booking_agreement"]' => array('checked' => FALSE), + ), + ), + */ + '#title' => t('I have read and agree to the following aims and expectations.', + array('!event' => $event->booking_eventname) + ), + '#description' => token_replace(variable_get('booking_registration_aims_rules_text'), booking_define_tokens()) + ); + } + else + { + //not inserting + $form['booking_agreement'] = array ( + '#type' => 'hidden', + '#value' => 1, + ); + + $form['your-details']['booking_amount_paid'] = array( + '#type' => 'textfield', + '#title' => t('Amount Paid'), + '#maxlength' => 10, + '#required' => FALSE, + '#default_value' => !empty($data->booking_amount_paid) ? $data->booking_amount_paid : '' + ); + + $form['your-details']['booking_total_pay_reqd'] = array( + '#type' => 'textfield', + '#title' => t('Total Amount Due'), + '#maxlength' => 10, + '#required' => FALSE, + '#default_value' => !empty($data->booking_total_pay_reqd) ? $data->booking_total_pay_reqd : '0.00' + ); + + $form['your-details']['booking_barcode'] = array( + '#type' => 'textfield', + '#title' => t('Barcode'), + '#maxlength' => 30, + '#size' => 30, + '#required' => FALSE, + '#default_value' => !empty($data->booking_barcode) ? $data->booking_barcode : '' + ); + + $form['your-details']['booking_readinggroup'] = array( + '#type' => 'textfield', + '#title' => t('Reading Group Allocation'), + '#maxlength' => 100, + '#default_value' => !empty($data->booking_readinggroup) ? $data->booking_readinggroup : '', + ); + } //end not-inserting check + + if (variable_get('booking_enable_passport', 0) == 1) + { + $form['passport-details'] = array( + '#type' => 'fieldset', + '#title' => 'Passport Details', + ); + $form['passport-details']['booking_passport_num'] = array( + '#type' => 'textfield', + '#title' => t('Passport Number'), + '#maxlength' => 45, + '#required' => FALSE, + '#default_value' => !empty($data->booking_passport_num) ? $data->booking_passport_num : '' + ); + $form['passport-details']['booking_passport_issue_location'] = array( + '#type' => 'textfield', + '#title' => t('City of Issue (eg Sydney)'), + '#maxlength' => 120, + '#required' => FALSE, + '#default_value' => !empty($data->booking_passport_issue_location) ? $data->booking_passport_issue_location : '' + ); + $form['passport-details']['booking_passport_issue_name'] = array( + '#type' => 'textfield', + '#title' => t('Exact name as listed on passport'), + '#maxlength' => 120, + '#required' => FALSE, + '#default_value' => !empty($data->booking_passport_issue_name) ? $data->booking_passport_issue_name : '' + ); + $form['passport-details']['booking_passport_expiry_date'] = array( + '#type' => 'date_select', + '#title' => t('Passport expiry date'), + '#default_value' => empty($data->booking_passport_expiry_date) ? '' : date("Y-m-d H:i:s", $data->booking_passport_expiry_date), + '#required' => FALSE, + '#date_format' => 'd/m/Y', + //'#date_label_position' => 'within', + '#date_year_range' => '+0:+13' + ); + } + + $form['contact-details'] = array( + '#type' => 'fieldset', + '#title' => 'Contact details', + ); + $form['contact-details']['booking_email'] = array( + '#type' => 'textfield', + '#title' => t('E-mail address'), + '#maxlength' => 100, + '#required' => TRUE, + '#default_value' => !empty($data->booking_email) ? $data->booking_email : '' + ); + + $form['contact-details']['booking_phone'] = array( + '#type' => 'textfield', + '#title' => t('Home Phone Number'), + '#maxlength' => 30, + '#size' => 35, + '#required' => FALSE, + '#default_value' => !empty($data->booking_phone) ? $data->booking_phone : '' + ); + $form['contact-details']['booking_mobile'] = array( + '#type' => 'textfield', + '#title' => t('Mobile Phone Number'), + '#size' => 35, + '#maxlength' => 30, + '#required' => FALSE, + '#default_value' => !empty($data->booking_mobile) ? $data->booking_mobile : '' + ); + + $form['contact-details']['booking_street'] = array( + '#type' => 'textfield', + '#title' => t('Street Address'), + '#maxlength' => 50, + '#required' => TRUE, + '#default_value' => !empty($data->booking_street) ? $data->booking_street : '' + ); + $form['contact-details']['booking_suburb'] = array( + '#type' => 'textfield', + '#title' => t('Suburb'), + '#maxlength' => 50, + '#required' => TRUE, + '#default_value' => !empty($data->booking_suburb) ? $data->booking_suburb : '' + ); + + + if ($inserting == TRUE) + { + $form['contact-details']['booking_state'] = array( + '#type' => 'select', + '#title' => t('State'), + '#required' => TRUE, + '#default_value' => !empty($data->booking_state) ? $data->booking_state : BOOKING_DEFAULT_STATE, + '#options' => _booking_state_options(), + ); + $form['contact-details']['booking_other_state'] = array( + '#type' => 'textfield', + '#title' => t('Please specify state'), + '#maxlength' => 50, + '#states' => array( + // Only show this field when the 'booking_state' is set to other. + 'visible' => array( + ':input[name="booking_state"]' => array('value' => 'Other'), + ), + ), + '#default_value' => '', + ); + } else { + //when modifying the node just show the textfield + $form['contact-details']['booking_state'] = array( + '#type' => 'textfield', + '#title' => t('State'), + '#maxlength' => 50, + '#default_value' => !empty($data->booking_state) ? $data->booking_state : '', + ); + } + + + $form['contact-details']['booking_postcode'] = array( + '#type' => 'textfield', + '#title' => t('Postal/Zip code'), + '#maxlength' => 8, + '#size' => 10, + '#required' => TRUE, + '#default_value' => !empty($data->booking_postcode) ? $data->booking_postcode : '' + ); + $form['contact-details']['booking_country'] = array( + '#type' => 'select', + '#title' => t('Country'), + '#required' => TRUE, + '#default_value' => variable_get('booking_country', empty($data->booking_country) ? variable_get('booking_default_country') : $data->booking_country), + '#options' => _booking_country_options(), + ); + + //emergency contact details + $form['emergency'] = array( + '#type' => 'fieldset', + '#title' => 'Emergency Contact Details', + '#description' => 'Please enter contact details for use in case of emergency', + ); + $form['emergency']['booking_guardian_name'] = array( + '#type' => 'textfield', + '#title' => t('Parent/Guardian Name'), + '#maxlength' => 100, + '#required' => TRUE, + '#default_value' => empty($data->booking_guardian_name) ? '' : $data->booking_guardian_name + ); + $form['emergency']['booking_guardian_type'] = array( + '#type' => 'radios', + '#title' => t('Relation to you'), + '#options' => $emergency_contact_type_options, + '#default_value' => empty($data->booking_guardian_type) ? 'parent' : $data->booking_guardian_type, + '#required' => TRUE + ); + $form['emergency']['booking_guardian_phone'] = array( + '#type' => 'textfield', + '#title' => t('Contact Number'), + '#maxlength' => 30, + '#size' => 30, + '#required' => TRUE, + '#default_value' => empty($data->booking_guardian_phone) ? '' : $data->booking_guardian_phone + ); + $form['emergency']['booking_guardian_phone_alt'] = array( + '#type' => 'textfield', + '#title' => t('Alternate Contact Number'), + '#maxlength' => 30, + '#size' => 30, + '#required' => FALSE, + '#default_value' => empty($data->booking_guardian_phone_alt) ? '' : $data->booking_guardian_phone_alt + ); + + if (variable_get('booking_enable_medicare', 1) == 1) + { + $form['emergency']['booking_medicare'] = array( + '#type' => 'textfield', + '#title' => t('Your Medicare Number'), + '#maxlength' => 15, + '#size' => 15, + '#required' => FALSE, + '#default_value' => empty($data->booking_medicare) ? '' : $data->booking_medicare + ); + } + + if (variable_get('booking_enable_helpareas', 1) == 1) + { + $form['help-areas'] = array( + '#type' => 'fieldset', + '#title' => 'Help Areas', + ); + + $form['help-areas']['booking_help_music'] = array( + '#type' => 'textfield', + '#title' => t('I can help with music by playing the following musical instrument(s)'), + '#maxlength' => 200, + '#required' => FALSE, + '#default_value' => !empty($data->booking_help_music) ? $data->booking_help_music : '' + ); + $form['help-areas']['booking_help_reading'] = array( + '#type' => 'checkbox', + '#title' => t('I can help with reading'), + '#default_value' => (!empty($data->booking_help_reading) && $data->booking_help_reading == 'Y') ? 1 : 0 + ); + $form['help-areas']['booking_help_chairing'] = array( + '#type' => 'checkbox', + '#title' => t('I can help with chairing'), + '#default_value' => (!empty($data->booking_help_chairing) && $data->booking_help_chairing == 'Y') ? 1 : 0 + ); + $form['help-areas']['booking_help_praying'] = array( + '#type' => 'checkbox', + '#title' => t('I can help with praying'), + '#default_value' => (!empty($data->booking_help_praying) && $data->booking_help_praying == 'Y') ? 1 : 0 + ); + $form['help-areas']['booking_help_meditations'] = array( + '#type' => 'checkbox', + '#title' => t('I can help with evening meditations'), + '#default_value' => (!empty($data->booking_help_meditations) && $data->booking_help_meditations == 'Y') ? 1 : 0 + ); + $form['help-areas']['booking_firstaid'] = array( + '#type' => 'checkbox', + '#title' => t('I am a qualified First Aid Officer'), + '#default_value' => (!empty($data->booking_firstaid) && $data->booking_firstaid == 'Y') ? 1 : 0 + ); + $form['help-areas']['booking_nurse'] = array( + '#type' => 'checkbox', + '#title' => t('I am a qualified Nurse'), + '#default_value' => (!empty($data->booking_nurse) && $data->booking_nurse == 'Y') ? 1 : 0 + ); + } + + if (variable_get('booking_enable_skills', 1) == 1) + { + $form['mission-experience'] = array( + '#type' => 'fieldset', + '#title' => 'Mission Work Experience', + ); + $form['mission-experience']['booking_has_mission_experience'] = array( + '#type' => 'checkbox', + '#title' => t('I have previous mission work experience'), + '#default_value' => (!empty($data->booking_has_mission_experience) && $data->booking_has_mission_experience == 'Y') ? 1 : 0 + ); + + $form['mission-experience']['booking_mission_experience_details'] = array( + '#type' => 'textfield', + '#title' => t("Please list the places you've done mission work previously"), + '#maxlength' => 200, + //'#size' => 100, + '#required' => FALSE, + '#states' => array( + // Only show this field when the 'booking_has_mission_experience' checkbox is enabled. + 'visible' => array( + ':input[name="booking_has_mission_experience"]' => array('checked' => TRUE), + ), + ), + '#default_value' => !empty($data->booking_mission_experience_details) ? $data->booking_mission_experience_details : '' + ); + $form['skill-areas'] = array( + '#type' => 'fieldset', + '#title' => 'Skills Section', + ); + $form['skill-areas']['booking_skills_builder'] = array( + '#type' => 'checkbox', + '#title' => t('I am an experienced builder'), + '#default_value' => (!empty($data->booking_skills_builder) && $data->booking_skills_builder == 'Y') ? 1 : 0 + ); + $form['skill-areas']['booking_skills_cooking'] = array( + '#type' => 'checkbox', + '#title' => t('I can assist with cooking'), + '#default_value' => (!empty($data->booking_skills_cooking) && $data->booking_skills_cooking == 'Y') ? 1 : 0 + ); + $form['skill-areas']['booking_skills_childminding'] = array( + '#type' => 'checkbox', + '#title' => t('I have child minding experience or am happy to work with children and sunday school students'), + '#default_value' => (!empty($data->booking_skills_childminding) && $data->booking_skills_childminding == 'Y') ? 1 : 0 + ); + $form['skill-areas']['booking_skills_language'] = array( + '#type' => 'checkbox', + '#title' => t('I can speak multiple languages'), + '#default_value' => (!empty($data->booking_skills_language) && $data->booking_skills_language == 'Y') ? 1 : 0 + ); + + $form['skill-areas']['booking_skills_language_details'] = array( + '#type' => 'textfield', + '#title' => t('Please list any languages other than English that you speak'), + '#maxlength' => 250, + '#required' => FALSE, + '#states' => array( + 'visible' => array( + ':input[name="booking_skills_language"]' => array('checked' => TRUE), + ), + ), + '#default_value' => !empty($data->booking_skills_language_details) ? $data->booking_skills_language_details : '' + ); + + $form['skill-areas']['booking_skills_other'] = array( + '#type' => 'checkbox', + '#title' => t('I have other skills that can assist in preaching activities'), + '#default_value' => (!empty($data->booking_skills_other) && $data->booking_skills_other == 'Y') ? 1 : 0 + ); + $form['skill-areas']['booking_skills_other_details'] = array( + '#type' => 'textfield', + '#title' => t('Please list any skills you believe will be helpful'), + '#maxlength' => 250, + '#required' => FALSE, + '#states' => array( + 'visible' => array( + ':input[name="booking_skills_other"]' => array('checked' => TRUE), + ), + ), + '#default_value' => !empty($data->booking_skills_other_details) ? $data->booking_skills_other_details : '' + ); + + } + + $form['misc-areas'] = array( + '#type' => 'fieldset', + '#title' => 'Miscellaneous', + ); + + if ($inserting == TRUE) + { + $form['misc-areas']['booking_dietary_check'] = array( + '#type' => 'checkbox', + '#title' => t('Special dietary requirements'), + '#default_value' => (!empty($data->booking_dietary) && $data->booking_dietary == 'Y') ? 1 : 0 + ); + + /* + $form['misc-areas']['booking_dietary'] = array( + '#type' => 'textfield', + '#title' => t('Please describe your dietary requirements.'), + '#maxlength' => 120, + '#required' => FALSE, + '#states' => array( + 'visible' => array( + ':input[name="booking_dietary_check"]' => array('checked' => TRUE), + ), + ), + '#default_value' => !empty($data->booking_dietary) ? $data->booking_dietary : '' + ); + */ + + $form['misc-areas']['booking_dietary'] = array( + '#type' => 'container', + '#children' => t('Please send an email to bookings@studyweek.net describing your dietary requirements.'), + '#states' => array( + 'visible' => array( + ':input[name="booking_dietary_check"]' => array('checked' => TRUE), + ), + ), + ); + + + $form['misc-areas']['booking_medical_conditions_check'] = array( + '#type' => 'checkbox', + '#title' => t('Special medical conditions'), + '#default_value' => (!empty($data->booking_medical_conditions) && $data->booking_medical_conditions == 'Y') ? 1 : 0 + ); + $form['misc-areas']['booking_medical_conditions'] = array( + '#type' => 'textfield', + '#title' => t('Please list any medical conditions we need to be aware of.'), + '#maxlength' => 120, + '#required' => FALSE, + '#states' => array( + 'visible' => array( + ':input[name="booking_medical_conditions_check"]' => array('checked' => TRUE), + ), + ), + '#default_value' => !empty($data->booking_medical_conditions) ? $data->booking_medical_conditions : '' + ); + + } else { + $form['misc-areas']['booking_dietary'] = array( + '#type' => 'textfield', + '#title' => t('Please describe your dietary requirements.'), + '#maxlength' => 120, + '#default_value' => !empty($data->booking_dietary) ? $data->booking_dietary : '' + ); + $form['misc-areas']['booking_medical_conditions'] = array( + '#type' => 'textfield', + '#title' => t('Please list any medical conditions we need to be aware of.'), + '#maxlength' => 120, + '#default_value' => !empty($data->booking_medical_conditions) ? $data->booking_medical_conditions : '' + ); + } + + if (variable_get('booking_enable_roommate', 0) == 1) + { + $form['misc-areas']['booking_room_mate1'] = array( + '#type' => 'textfield', + '#title' => t('I would like to share a room with'), + '#maxlength' => 200, + '#required' => FALSE, + '#default_value' => !empty($data->booking_room_mate1) ? $data->booking_room_mate1 : '', + ); + } + + + if ($inserting == TRUE) { + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Register'), + ); + } + return $form; +} + + + +function booking_form_validate($form, &$form_state) { + return _booking_validate($form_state['values']['form_id'], $form_state['values']); +} + +function _booking_validate($node, &$form_state) { + global $event; + + //in case the date of birth field hasn't been filled out + //watchdog('booking', 'Blank date of birth checking: @info', array('@info' => var_export($form_state['booking_dob'], TRUE))); + $dob_check = $form_state['booking_dob']['day'] != '' && $form_state['booking_dob']['month'] != '' && $form_state['booking_dob']['year'] != '' ? _date_to_ts($form_state['booking_dob']) : 0; + + //Verify this is not a duplicate registration + //try and find the person in the database for this event + $person = db_query("SELECT person.nid, person.booking_tempid " . + "FROM {booking_person} person " . + "WHERE booking_firstname = :first AND booking_lastname = :last AND booking_dob = :dob AND booking_event_id = :eid", + array(':first' => $form_state['booking_firstname'], ':last' => $form_state['booking_lastname'], ':dob' => $dob_check, + ':eid' => $event->eid)) + ->fetchObject(); + + if ($person) + { + if ((strlen($person->booking_tempid) > 0) && (variable_get('booking_use_paypal', 0) == 1)) + { + //they have registered but not paid, so give them the payment link + form_set_error('booking_firstname', + t('Our records indicate that you are part-way through the registration process. Please !click to complete the process.', + array('!click' => l('click here', 'confirm/' . $person->booking_tempid))) + ); + return; + } + else + { + form_set_error('booking_firstname', + t('Our records indicate that you have already registered. If you believe this to be incorrect, please !contact using the details provided.', + array('!contact' => l('contact us', 'contact-us'))) + ); + } + } + + //verify partner id is in the correct format + if ($form_state['booking_partner_id'] != '') + { + + if (! is_numeric($form_state['booking_partner_id'] )) + { + form_set_error('booking_partner_id', + t('You have entered an invalid partner registration id. Please ensure you are using only the registration reference number your partner received via email. If you believe this to be incorrect, please !contact using the details provided.', + array('!contact' => l('contact us', 'contact'))) + ); + } + + //check that the partner exists + $partner = db_query("SELECT person.nid, person.booking_married " . + "FROM {booking_person} person " . + "WHERE nid = :nid AND person.booking_married = 'Y'", + array(':nid' => $form_state['booking_partner_id'])) + ->fetchObject(); + + //watchdog('booking', 'Checking for partner via query: @info', array('@info' => $partner->__toString())); + + if (! $partner) + { + form_set_error('booking_partner_id', + t('Our records do not indicate that the supplied registration ID of your spouse is correct. Please ensure you are using only the number that relates to their registration. If you believe this to be incorrect, please !contact using the details provided.', + array('!contact' => l('contact us', 'contact'))) + ); + } + } + + //watchdog('booking', 'Form validate data: @info', array('@info' => var_export($form_state, TRUE))); + $email = (isset($form_state['booking_email']) ? $form_state['booking_email'] : $node->booking_email); + if (strlen(trim($email)) > 0 && !_valid_email_address($email)) + form_set_error('booking_email', t('You must enter a valid e-mail address. Please ensure you typed your email address correctly.')); + + //calculate DOB limit as defined by configuration + $max_dob_matches = _split_date(variable_get('booking_max_dob','0')); + + $max_dob_check= mktime(12, 0, 0, $max_dob_matches[2], $max_dob_matches[3], $max_dob_matches[1]); + //if DOB on form is more recent than DOB limit, display validation error + if ($dob_check > $max_dob_check) + form_set_error('booking_dob', t('Unfortunately you are too young to attend !event.', + array('!event' => variable_get('booking_event_name','this event')))); + + //check the terms and conditions have been agreed to + if ($form_state['booking_agreement'] == 0) + form_set_error('booking_agreement', t('You must read and agree with the aims and expectations prior to submitting this form.')); + + //check the medicare number for people in Australia + if (variable_get('booking_enable_medicare', 1) == 1 && $form_state['booking_country'] == 'Australia') + { + //proper validation routine at http://dyball.wordpress.com/2007/12/05/validation-of-medicare-numbers/ + if (! _valid_medicare_number($form_state['booking_medicare'])) + { + form_set_error('booking_medicare', + t('You have entered an invalid medicare number. Please check your medicare card and re-enter the number. ' . + 'If you believe this to be incorrect, please !contact.', + array('!contact' => l('send us an email', 'mailto:' . variable_get('booking_contact_email') . '?subject=Invalid Medicare Number'))) + ); + } + } + + //verify passport number + if (variable_get('booking_enable_passport', 0) == 1 && $form_state['booking_country'] == 'Australia') + { + if (($form_state['booking_passport_num'] != '') && (! _valid_passport_number($form_state['booking_passport_num']))) + { + form_set_error('booking_passport_num', + t('You have entered an invalid passport number. Please check your passport and re-enter the number. ' . + 'If you believe this to be incorrect, please !contact.', + array('!contact' => l('send us an email', 'mailto:' . variable_get('booking_contact_email') . '?subject=Invalid Passport Number'))) + ); + } + } + + //check at least one phone number has been entered + if ( ($form_state['booking_phone'] == '' ) && ($form_state['booking_mobile'] == '') ) + form_set_error('booking_mobile', t('You must enter at least one phone number, either a mobile phone or a home phone number.')); + if (($form_state['booking_phone'] != '' ) && (!_valid_phone_number($form_state['booking_phone']))) + form_set_error('booking_phone', t('You have entered an invalid home phone number.')); + if (($form_state['booking_mobile'] != '' ) && (!_valid_phone_number($form_state['booking_mobile']))) + form_set_error('booking_mobile', t('You have entered an invalid mobile phone number.')); + + //verify guardian phone number(s) + if (($form_state['booking_guardian_phone'] != '' ) && (!_valid_phone_number($form_state['booking_guardian_phone']))) + form_set_error('booking_guardian_phone', t('You have entered an contact phone number for your emergency contact.')); + + //verify that a state has been entered if "Other" was selected + if (($form_state['booking_state'] == 'Other' ) && ($form_state['booking_other_state'] == '')) + form_set_error('booking_other_state', t('You must enter your State in the address section of the Contact details.')); +} + +function booking_form_submit($form, &$form_state) { + global $event; + + $values = $form_state['input']; + + //get DOB from form + $dob = _datearray_to_ts($values['booking_dob']); + + //retrieve an object with the booking price + $payment_total_price = db_query("SELECT booking_price FROM {booking_price} where pid = :pid", + array(':pid' => $form_state['input']['booking_payment_id'])) + ->fetchObject(); + + //make a new node object + $node = new stdClass(); + $node = node_type_set_defaults(); + $node->title = t('!event registration: !name', + array('!event' => $event->booking_eventname, '!name' => $values['booking_firstname'] . ' ' . $values['booking_lastname'])); + $node->type = 'booking'; + $node->status = 1; // set published to true + $node->promote = 0; // prevent display on front page + $node->language = LANGUAGE_NONE; + $node->created = REQUEST_TIME; + $node->changed = REQUEST_TIME; + + $node->booking_firstname = trim($values['booking_firstname']); + $node->booking_lastname = trim($values['booking_lastname']); + $node->booking_gender = $values['booking_gender']; + $node->booking_dob = $dob; + $node->booking_status = 0; //zero means not yet coming. Only change to 1 when a payment is made + + //passport details + $node->booking_passport_num = empty($values['booking_passport_num']) ? '' : $values['booking_passport_num']; + $node->booking_passport_issue_location = empty($values['booking_passport_issue_location']) ? '' : $values['booking_passport_issue_location']; + $node->booking_passport_issue_name = empty($values['booking_passport_issue_name']) ? '' : $values['booking_passport_issue_name']; + $node->booking_passport_expiry_date = empty($values['booking_passport_expiry_date']) ? '0' : _datearray_to_ts($values['booking_passport_expiry_date']); + + //calculate booking_payment_id based on form choice of student or worker + //$worker_type = db_result(db_query("SELECT pid FROM {booking_price} where booking_eventid = %d AND booking_price_descrip='%s'", + // EVENTID, $values['booking_worker_type'] )); + $node->booking_payment_id = $values['booking_payment_id']; + + $node->booking_street = $values['booking_street']; + $node->booking_suburb = $values['booking_suburb']; + $node->booking_postcode = $values['booking_postcode']; + $node->booking_country = $values['booking_country']; + + //allow for user-entered value if the state is not already listed + if ($values['booking_state'] == 'Other') { + $node->booking_state = $values['booking_other_state']; + } else { + $node->booking_state = $values['booking_state']; + } + + $node->booking_phone = $values['booking_phone']; + $node->booking_mobile = $values['booking_mobile']; + $node->booking_email = $values['booking_email']; + $node->booking_ecclesia = $values['booking_ecclesia']; + $node->booking_baptised = ($values['booking_baptised'] == 1 ? 'Y' : 'N'); + $node->booking_married = ($values['booking_married'] == 1 ? 'Y' : 'N'); + $node->booking_partner_name = $values['booking_partner_name']; + $node->booking_partner_id = empty($values['booking_partner_id']) ? 0 : $values['booking_partner_id']; + + //emergency contact info + $node->booking_guardian_name = $values['booking_guardian_name']; + $node->booking_guardian_type = $values['booking_guardian_type']; + $node->booking_guardian_phone = $values['booking_guardian_phone']; + $node->booking_guardian_phone_alt = $values['booking_guardian_phone_alt']; + $node->booking_medicare = empty($values['booking_medicare']) ? 0 : $values['booking_medicare']; + + //fields that may or may not have been present in the initial form + $node->booking_help_music = empty($values['booking_help_music']) ? '' : $values['booking_help_music']; + $node->booking_help_meditations = empty($values['booking_help_meditations']) ? '' : $values['booking_help_meditations']; + $node->booking_help_praying = empty($values['booking_help_praying']) ? '' : $values['booking_help_praying']; + $node->booking_help_reading = empty($values['booking_help_reading']) ? 'N' : ($values['booking_help_reading'] == 1 ? 'Y' : 'N'); + $node->booking_help_chairing = empty($values['booking_help_chairing']) ? 'N' : ($values['booking_help_chairing'] == 1 ? 'Y' : 'N'); + $node->booking_help_readgroup_lead = empty($values['booking_help_readgroup_lead']) ? 'N' : ($values['booking_help_readgroup_lead'] == 1 ? 'Y' : 'N'); + $node->booking_help_discussgroup_lead = empty($values['booking_help_discussgroup_lead']) ? 'N' : ($values['booking_help_discussgroup_lead'] == 1 ? 'Y' : 'N'); + $node->booking_firstaid = empty($values['booking_firstaid']) ? 'N' : ($values['booking_firstaid'] == 1 ? 'Y' : 'N'); + $node->booking_nurse = empty($values['booking_nurse']) ? 'N' : ($values['booking_nurse'] == 1 ? 'Y' : 'N'); + $node->booking_lifesaver = empty($values['booking_lifesaver']) ? 'N' : ($values['booking_lifesaver'] == 1 ? 'Y' : 'N'); + $node->booking_doctor = empty($values['booking_doctor']) ? 'N' : ($values['booking_doctor'] == 1 ? 'Y' : 'N'); + $node->booking_dietary = empty($values['booking_dietary']) ? 'N/A' : $values['booking_dietary']; + $node->booking_medical_conditions = empty($values['booking_medical_conditions']) ? 'N/A' : $values['booking_medical_conditions']; + $node->booking_mission_experience_details = empty($values['booking_mission_experience_details']) ? 'N/A' : $values['booking_mission_experience_details']; + $node->booking_has_mission_experience = empty($values['booking_has_mission_experience']) ? 'N' : ($values['booking_has_mission_experience'] == 1 ? 'Y' : 'N'); + $node->booking_skills_builder = empty($values['booking_skills_builder']) ? 'N' : ($values['booking_skills_builder'] == 1 ? 'Y' : 'N'); + $node->booking_skills_cooking = empty($values['booking_skills_cooking']) ? 'N' : ($values['booking_skills_cooking'] == 1 ? 'Y' : 'N'); + $node->booking_skills_childminding = empty($values['booking_skills_childminding']) ? 'N' : ($values['booking_skills_childminding'] == 1 ? 'Y' : 'N'); + $node->booking_skills_language = empty($values['booking_skills_language']) ? 'N' : ($values['booking_skills_language'] == 1 ? 'Y' : 'N'); + $node->booking_skills_language_details = empty($values['booking_skills_language_details']) ? 'N/A' : $values['booking_skills_language_details']; + $node->booking_skills_other = empty($values['booking_skills_other']) ? 'N' : ($values['booking_skills_other'] == 1 ? 'Y' : 'N'); + $node->booking_skills_other_details = empty($values['booking_skills_other_details']) ? 'N/A' : $values['booking_skills_other_details']; + + + //potential fields for future + //$node->booking_payment_method = $payment_method; + $node->booking_room_mate1 = empty($values['booking_room_mate1']) ? '' : $values['booking_room_mate1']; + $node->booking_room_mate2 = empty($values['booking_room_mate2']) ? '' : $values['booking_room_mate2']; + $node->booking_shirt_size = empty($values['booking_shirt_size']) ? 'N/A' : $values['booking_shirt_size']; + + //fields only configured by admin + $node->booking_readinggroup = !empty($values['booking_readinggroup']) ? $values['booking_readinggroup'] : ''; + $node->booking_timestamp = REQUEST_TIME; + + //internal fields + $tempid = _booking_uuidSecure(); + $node->booking_tempid = $tempid; + $node->booking_event_id = $event->eid; + $node->booking_amount_paid = 0; + $node->booking_total_pay_reqd = $payment_total_price->booking_price; + + //watchdog('booking', 'Node data: @info', array('@info' => var_export($node, TRUE))); + $foo = node_submit(&$node); + //watchdog('booking', 'Node data after submit: @info', array('@info' => var_export($foo, TRUE))); + $blah = node_save($foo); + //watchdog('booking', 'Node data after save: @info', array('@info' => var_export($blah, TRUE))); + + //if booking_partner_id is set, make sure the nid it refers to has this node as its booking_partner_id + if ($node->booking_partner_id != 0) + { + $partner = db_query("Select booking_partner_id from {booking_person} where nid = :nid", + array(':nid' => $node->booking_partner_id)) + ->fetchObject(); + if ($partner->booking_partner_id == 0) + { + watchdog('booking', 'Updating partner node !partner to refer to this node !nid', + array('!partner' => $node->booking_partner_id, '!nid' => $node->nid)); + //update the partner id of the partner to refer to this node + db_update('booking_person') + ->fields(array( + 'booking_partner_id' => $node->nid, + )) + ->condition('nid', $node->booking_partner_id) + ->execute(); + } + } + + //check whether we should send an automatic email + if (variable_get('booking_auto_confirm_email', 0) == 1) + { + //send the person an email + _booking_registration_email($node->nid, FALSE, FALSE); + } else + { + //just send a notification email + _booking_regn_notifyonly_email($node, FALSE); + } + //redirect the user to the confirmation page + $form_state['redirect'] = array('confirm/' . $tempid); +} + +function booking_load($nodes) { + //watchdog('booking', 'Loading node with params: @info', array('@info' => var_export($nodes, TRUE))); + + // note that $nodes is an array of object references, keyed by nid + // grab the data from our module tables + // without an array of field names, 'SELECT * FROM table_alias_name' is assumed + + $query = db_select('booking_person', 'p'); + //perform an inner join + $query->join('booking_price', 'pr', 'p.booking_payment_id = pr.pid'); + //filter the results and select the appropriate fields + $query->condition('p.nid', array_keys($nodes), 'IN') + ->fields('p') + ->fields('pr', array('booking_price', 'booking_price_descrip')); + //get the query result + $result = $query->execute(); + + //watchdog('booking', 'Loading node via query: @info', array('@info' => $query->__toString())); + + //add that data to the array of node references + foreach ($result as $record) + { + //watchdog('booking', 'This node looks like: @info', array('@info' => var_export($record, TRUE))); + // run through each result row and add in the needed attributes + foreach ($record as $key => $value) + { + $nodes[$record->nid]->$key = $value; + } + } + + //watchdog('booking', 'Final loaded node: @info', array('@info' => var_export($nodes, TRUE))); + // no return necessary since $nodes array members reference objects global to this function +} + +function _booking_insert($node) { + //watchdog('booking', 'Inserting node: @info', array('@info' => var_export($node, TRUE))); + + db_insert('booking_person') + ->fields(array( + 'nid' => $node->nid, + 'booking_event_id' => $node->booking_event_id, + 'booking_firstname' => ucwords($node->booking_firstname), + 'booking_lastname' => ucwords($node->booking_lastname), + 'booking_dob' => $node->booking_dob, + 'booking_passport_num' => $node->booking_passport_num, + 'booking_passport_issue_location' => $node->booking_passport_issue_location, + 'booking_passport_issue_name' => $node->booking_passport_issue_name, + 'booking_passport_expiry_date' => $node->booking_passport_expiry_date, + 'booking_gender' => $node->booking_gender, + 'booking_street' => $node->booking_street, + 'booking_suburb' => $node->booking_suburb, + 'booking_postcode' => $node->booking_postcode, + 'booking_state' => $node->booking_state, + 'booking_country' => $node->booking_country, + 'booking_phone' => $node->booking_phone, + 'booking_mobile' => $node->booking_mobile, + 'booking_email' => $node->booking_email, + 'booking_timestamp' => $node->booking_timestamp, + 'booking_ecclesia' => $node->booking_ecclesia, + 'booking_baptised' => $node->booking_baptised, + 'booking_married' => $node->booking_married, + 'booking_partner_name' => $node->booking_partner_name, + 'booking_partner_id' => $node->booking_partner_id, + 'booking_room_mate1' => $node->booking_room_mate1, + 'booking_room_mate2' => $node->booking_room_mate2, + 'booking_shirt_size' => empty($node->booking_shirt_size) ? 'N/A' : $node->booking_shirt_size, + 'booking_help_music' => $node->booking_help_music, + 'booking_help_praying' => $node->booking_help_praying, + 'booking_help_meditations' => $node->booking_help_meditations, + 'booking_help_reading' => $node->booking_help_reading, + 'booking_help_chairing' => $node->booking_help_chairing, + 'booking_help_readgroup_lead' => $node->booking_help_readgroup_lead, + 'booking_help_discussgroup_lead' => $node->booking_help_discussgroup_lead, + 'booking_readinggroup' => $node->booking_readinggroup, + 'booking_tempid' => $node->booking_tempid, + 'booking_payment_id' => $node->booking_payment_id, + 'booking_amount_paid' => $node->booking_amount_paid, + 'booking_total_pay_reqd' => $node->booking_total_pay_reqd, + 'booking_guardian_name' => $node->booking_guardian_name, + 'booking_guardian_type' => $node->booking_guardian_type, + 'booking_guardian_phone' => $node->booking_guardian_phone, + 'booking_guardian_phone_alt' => $node->booking_guardian_phone_alt, + 'booking_medicare' => empty($node->booking_medicare) ? '' : $node->booking_medicare, + 'booking_lifesaver' => $node->booking_lifesaver, + 'booking_firstaid' => $node->booking_firstaid, + 'booking_nurse' => $node->booking_nurse, + 'booking_doctor' => $node->booking_doctor, + 'booking_dietary' => $node->booking_dietary, + 'booking_medical_conditions' => $node->booking_medical_conditions, + 'booking_has_mission_experience' => $node->booking_has_mission_experience, + 'booking_mission_experience_details' => $node->booking_mission_experience_details, + 'booking_skills_builder' => $node->booking_skills_builder, + 'booking_skills_cooking' => $node->booking_skills_cooking, + 'booking_skills_childminding' => $node->booking_skills_childminding, + 'booking_skills_language' => $node->booking_skills_language, + 'booking_skills_language_details' => $node->booking_skills_language_details, + 'booking_skills_other' => $node->booking_skills_other, + 'booking_skills_other_details' => $node->booking_skills_other_details, + 'booking_status' => $node->booking_status, + )) + ->execute(); +} + +/** + * Convert $node attribute values (from form) into appropriate formats for persistence + * + * @param $node from form submission + * @return nothing + */ +function _booking_update($node) { + global $event; + + //before we update this user, check what their previous registration status was + $previous_status = db_query("SELECT booking_status, booking_payment_id, booking_total_pay_reqd, booking_amount_paid FROM {booking_person} where nid = :nid", array( + ':nid' => $node->nid)) + ->fetchObject(); + + //watchdog('booking', 'Updating node: @info', array('@info' => var_export($node, TRUE))); + db_update('booking_person') + ->fields(array ( + 'booking_firstname' => $node->booking_firstname, + 'booking_lastname' => $node->booking_lastname, + 'booking_dob' => _date_to_ts($node->booking_dob), + 'booking_passport_num' => $node->booking_passport_num, + 'booking_passport_issue_location' => $node->booking_passport_issue_location, + 'booking_passport_issue_name' => $node->booking_passport_issue_name, + 'booking_passport_expiry_date' => _date_to_ts($node->booking_passport_expiry_date), + 'booking_gender' => $node->booking_gender, + 'booking_street' => $node->booking_street, + 'booking_suburb' => $node->booking_suburb, + 'booking_postcode' => $node->booking_postcode, + 'booking_state' => $node->booking_state, + 'booking_country' => $node->booking_country, + 'booking_phone' => $node->booking_phone, + 'booking_mobile' => $node->booking_mobile, + 'booking_email' => $node->booking_email, + 'booking_timestamp' => $node->booking_timestamp, + 'booking_ecclesia' => $node->booking_ecclesia, + 'booking_baptised' => ($node->booking_baptised == 1 ? 'Y' : 'N'), + 'booking_married' => ($node->booking_married == 1 ? 'Y' : 'N'), + 'booking_partner_name' => $node->booking_partner_name, + 'booking_partner_id' => $node->booking_partner_id, + 'booking_room_mate1' => $node->booking_room_mate1, + 'booking_room_mate2' => $node->booking_room_mate2, + 'booking_shirt_size' => $node->booking_shirt_size, + 'booking_help_music' => $node->booking_help_music, + 'booking_help_praying' => ($node->booking_help_praying == 1 ? 'Y' : 'N'), + 'booking_help_meditations' => ($node->booking_help_meditations == 1 ? 'Y' : 'N'), + 'booking_help_reading' => ($node->booking_help_reading == 1 ? 'Y' : 'N'), + 'booking_help_chairing' => ($node->booking_help_chairing == 1 ? 'Y' : 'N'), + 'booking_help_readgroup_lead' => ($node->booking_help_readgroup_lead == 1 ? 'Y' : 'N'), + 'booking_help_discussgroup_lead' => ($node->booking_help_discussgroup_lead == 1 ? 'Y' : 'N'), + 'booking_readinggroup' => $node->booking_readinggroup, + 'booking_tempid' => $node->booking_tempid, + 'booking_payment_id' => $node->booking_payment_id, + 'booking_total_pay_reqd' => $node->booking_total_pay_reqd, + 'booking_amount_paid' => $node->booking_amount_paid, + 'booking_guardian_name' => $node->booking_guardian_name, + 'booking_guardian_type' => $node->booking_guardian_type, + 'booking_guardian_phone' => $node->booking_guardian_phone, + 'booking_guardian_phone_alt' => $node->booking_guardian_phone_alt, + 'booking_medicare' => $node->booking_medicare, + 'booking_lifesaver' => ($node->booking_lifesaver == 1 ? 'Y' : 'N'), + 'booking_firstaid' => ($node->booking_firstaid == 1 ? 'Y' : 'N'), + 'booking_nurse' => ($node->booking_nurse == 1 ? 'Y' : 'N'), + 'booking_doctor' => ($node->booking_doctor == 1 ? 'Y' : 'N'), + 'booking_dietary' => $node->booking_dietary, + 'booking_medical_conditions' => $node->booking_medical_conditions, + 'booking_has_mission_experience' => ($node->booking_has_mission_experience == 1 ? 'Y' : 'N'), + 'booking_mission_experience_details' => $node->booking_mission_experience_details, + 'booking_skills_builder' => ($node->booking_skills_builder == 1 ? 'Y' : 'N'), + 'booking_skills_cooking' => ($node->booking_skills_cooking == 1 ? 'Y' : 'N'), + 'booking_skills_childminding' => ($node->booking_skills_childminding == 1 ? 'Y' : 'N'), + 'booking_skills_language' => ($node->booking_skills_language == 1 ? 'Y' : 'N'), + 'booking_skills_language_details' => $node->booking_skills_language_details, + 'booking_skills_other' => ($node->booking_skills_other == 1 ? 'Y' : 'N'), + 'booking_skills_other_details' => $node->booking_skills_other_details, + 'booking_status' => $node->booking_status, + )) + ->condition('nid', $node->nid) + ->execute(); + + //if booking_partner_id is set, make sure the nid it refers to has this node as its booking_partner_id + if ($node->booking_partner_id != 0) + { + $partner = db_query("Select booking_partner_id from {booking_person} where nid = :nid", + array(':nid' => $node->booking_partner_id)) + ->fetchObject(); + if ($partner->booking_partner_id == 0) + { + watchdog('booking', 'Updating partner node !partner to refer to this node !nid', + array('!partner' => $node->booking_partner_id, '!nid' => $node->nid)); + //update the partner id of the partner to refer to this node + db_update('booking_person') + ->fields(array( + 'booking_partner_id' => $node->nid, + )) + ->condition('nid', $node->booking_partner_id) + ->execute(); + } + } + + + //now check if someone needs to move from the waiting list to the booked in list + if ($previous_status->booking_status == 1 && $node->booking_status == 3) + { + watchdog('booking', 'Detected person moving from Booked In list to No Longer Coming'); + + //check if there is room on the booked-in list + if (_booking_check_bookings_full() == False) + { + watchdog('booking', 'Looks like there was room on the booked in list, so lets tell the next person'); + //find the first person on the waiting list + $temp_nid = _booking_get_waitinglist_top(); + + if ($temp_nid != -1) //-1 means there was no one on the waiting list + { + //update their registration status + _booking_change_status($temp_nid,1); + + //send them an email + _booking_promoted_from_waitinglist_email($temp_nid); + } + } + else + watchdog('booking', 'Still no room on the booked in list though.'); + } + //if we're not automatically sending emails on registration, then check if + //someone moved from not-paid to booked-in (ie, manual payment process) + elseif (variable_get('booking_auto_confirm_email', 0) == 0 && $previous_status->booking_status == 0 && $node->booking_status == 1) + { + watchdog('booking', 'Detected person moving from Not Paid list to Booked In list'); + + //make sure the booked in list isn't full + if (_booking_check_bookings_full() == False) + { + watchdog('booking', 'Confirmed room on the booked in list'); + //send them an email + _booking_registration_email($node->nid, FALSE, FALSE); + //_booking_promoted_from_waitinglist_email($node->nid); + } + } + + //if the payment ID has changed then update the total pay required + if ($previous_status->booking_payment_id != $node->booking_payment_id) + { + $total_due = 0; + watchdog('booking', 'Detected payment type change for attendee'); + + //look up the total pay required for the new payment id + $price = db_select('booking_price', 'p') + ->condition('p.pid', $node->booking_payment_id,'=') + ->fields('p', array('booking_price', 'booking_late_price')) + ->execute() + ->fetchObject(); + + //check for early bird rate or full rate + if (_booking_is_earlybird() == TRUE) + $total_due = $price->booking_price; + else + $total_due = $price->booking_late_price; + + //update the person with the new total pay required + db_update('booking_person') + ->fields(array( + 'booking_total_pay_reqd' => $total_due, + )) + ->condition('nid', $node->nid) + ->execute(); + } + +} + +function _booking_delete($node) { + + $last = $node->booking_lastname; + $first = $node->booking_firstname; + + $num_deleted = db_delete('booking_person') + ->condition('nid', $node->nid) + ->execute(); + + $message = t("Successfully deleted !num row(s), corresponding to '!last, !first'", + array('!num' => $num_deleted, '!last' => $last, '!first' => $first)); + + drupal_set_message($message, $type = 'status'); + +} + + +function booking_view($node, $view_mode) { + + //calculate the price owed by this person + $price_lookup = db_query("SELECT booking_price_descrip, booking_price, booking_late_price FROM {booking_price} where pid = :pid ", + array(':pid' => $node->booking_payment_id)) + ->fetchObject(); + $price = _booking_is_earlybird() == true ? $price_lookup->booking_price : $price_lookup->booking_late_price; + $payment_type = $price_lookup->booking_price_descrip . ' ($' . $price . ')'; + + if ($node->booking_partner_id != 0) + { + $partner = db_query("Select booking_firstname, booking_lastname from {booking_person} where nid = :nid", + array(':nid' => $node->booking_partner_id)) + ->fetchObject(); + $partner_name = $partner->booking_firstname . " " . $partner->booking_lastname; + } + else + $partner_name = "N/A"; + + $header = array('Attribute', 'Value'); + $rows = array(); + $rows[] = array(t('Date/Time registered:'), t('!timestamp', array('!timestamp' => format_date($node->booking_timestamp, 'custom', 'd/m/Y H:i')))); + $rows[] = array(t('Name:'), t('!first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname))); + $rows[] = array(t('Gender:'), t('!gender', array('!gender' => $node->booking_gender == 'M' ? 'Male' : 'Female'))); + $rows[] = array(t('Status:'), t('!status', array('!status' => _booking_status_generate($node->booking_status)))); + $rows[] = array(t('Barcode:'), t('!id', array('!id' => $node->booking_barcode))); + $rows[] = array(t('Date of birth:'), t('!dob', array('!dob' => format_date($node->booking_dob, 'custom', 'd/m/Y')))); + $rows[] = array(t('Email address:'), t('!email', array('!email' => $node->booking_email))); + + if (variable_get('booking_enable_passport', 1) == 1) + { + $rows[] = array(t('Passport Number:'), $node->booking_passport_num); + $rows[] = array(t('Passport Expiry:'), t('!timestamp', array('!timestamp' => _booking_convert_ts($node->booking_passport_expiry_date)->format('d/m/Y')))); + $rows[] = array(t('Passport Exact Issued Name:'), $node->booking_passport_issue_name); + $rows[] = array(t('Passport Issue Location:'), $node->booking_passport_issue_location); + } + + $rows[] = array(t('Payment Type Selected:'), t('!amount_paid', array('!amount_paid' => $payment_type))); + $rows[] = array(t('Amount Paid:'), t('!amount_paid', array('!amount_paid' => $node->booking_amount_paid))); + $rows[] = array(t('Total Amount Due:'), t('!amount_paid', array('!amount_paid' => $node->booking_total_pay_reqd))); + $rows[] = array(t('Reading Group:'), t('!group', array('!group' => $node->booking_readinggroup))); + + if (variable_get('booking_enable_tshirts', 0) == 1) + $rows[] = array(t('Hoodie Size:'), $node->booking_shirt_size); + + + $rows[] = array(t('Home Phone Number:'), t('!home', array('!home' => $node->booking_phone))); + $rows[] = array(t('Mobile Phone Number:'), t('!mob', array('!mob' => $node->booking_mobile))); + $rows[] = array(t('Postal Address:'), t('!street
!suburb !state !code
!country', + array('!street' => $node->booking_street, '!suburb' => $node->booking_suburb, + '!state' => ($node->booking_state == 'N/A' ? '' : $node->booking_state), + '!code' => $node->booking_postcode, + '!country' => $node->booking_country))); + $rows[] = array(t('Ecclesia:'), t('!ecclesia', array('!ecclesia' => $node->booking_ecclesia))); + $rows[] = array(t('Baptised:'), t('!ans', array('!ans' => ($node->booking_baptised == 'Y' ? 'Yes' : 'No')))); + $rows[] = array(t('Married:'), t('!ans', array('!ans' => ($node->booking_married == 'Y' ? 'Yes' : 'No')))); + //$rows[] = array(t("If married, attending partner's name:"), t('!name', array('!name' => $node->booking_partner_name))); + $rows[] = array(t('Linked Partner:'), t($partner_name)); + $rows[] = array(t('Emergency Contact Name:'), $node->booking_guardian_name); + $rows[] = array(t('Emergency Contact Relationship:'), $node->booking_guardian_type); + $rows[] = array(t('Emergency Contact Phone:'), $node->booking_guardian_phone); + $rows[] = array(t('Emergency Contact Alternate Phone:'), $node->booking_guardian_phone_alt); + if (variable_get('booking_enable_medicare', 1) == 1) + $rows[] = array(t('Medicare Number:'), $node->booking_medicare); + + $rows[] = array(t('Special Dietary Requirements:'), $node->booking_dietary); + $rows[] = array(t('Special Medical Conditions:'), $node->booking_medical_conditions); + + if (variable_get('booking_enable_roommate', 0) == 1) + { + $rows[] = array(t('Preferred room-mates:'), t('!room', array('!room' => $node->booking_room_mate1 . ' ' . $node->booking_room_mate2))); + } + + if (variable_get('booking_enable_helpareas', 1) == 1) + { + $rows[] = array(t('Qualified Life Saver:'), $node->booking_lifesaver == 'Y' ? 'Yes' : 'No'); + $rows[] = array(t('Qualified First Aider:'), $node->booking_firstaid == 'Y' ? 'Yes' : 'No'); + $rows[] = array(t('Qualified Nurse:'), $node->booking_nurse == 'Y' ? 'Yes' : 'No'); + $rows[] = array(t('Qualified Doctor:'), $node->booking_doctor == 'Y' ? 'Yes' : 'No'); + $help_areas = ''; + if ($node->booking_help_music) + $help_areas .= 'music: ' . $node->booking_help_music . ', '; + if ($node->booking_help_reading == 'Y') + $help_areas .= 'reading, '; + if ($node->booking_help_chairing == 'Y') + $help_areas .= 'chairing, '; + if ($node->booking_help_readgroup_lead == 'Y') + $help_areas .= 'reading group leading, '; + if ($node->booking_help_discussgroup_lead == 'Y') + $help_areas .= 'discussion group leading, '; + if ($node->booking_help_praying == 'Y') + $help_areas .= 'praying, '; + if ($node->booking_help_meditations == 'Y') + $help_areas .= 'meditations, '; + + $rows[] = array(t('Help areas:'), t('!help', array('!help' => $help_areas))); + } + + if (variable_get('booking_enable_skills', 1) == 1) + { + $skill_areas = ''; + if ($node->booking_skills_builder == 'Y') + $skill_areas .= 'builder, '; + if ($node->booking_skills_cooking == 'Y') + $skill_areas .= 'cook, '; + if ($node->booking_skills_childminding == 'Y') + $skill_areas .= 'child minding, '; + if ($node->booking_skills_language == 'Y') + $skill_areas .= 'speaks languages: ' . $node->booking_skills_language_details . ', '; + if ($node->booking_skills_other == 'Y') + $skill_areas .= 'other skills: ' . $node->booking_skills_other_details . ', '; + $rows[] = array(t('Mission related skills:'), t('!value', array('!value' => $skill_areas))); + $rows[] = array(t('Previous Mission Experience:'), $node->booking_mission_experience_details); + } + + $rows[] = array(t('Temporary UUID:'), $node->booking_tempid); + + $node->content['details'] = array( + '#markup' => theme('table', array('header' => $header, 'rows' => $rows)), + '#weight' => 1, + ); + return $node; + +} diff --git a/booking.reports.inc b/booking.reports.inc new file mode 100644 index 0000000..e15f293 --- /dev/null +++ b/booking.reports.inc @@ -0,0 +1,404 @@ + $event->eid)); + + + foreach ($result as $person) { + $rows[] = array( + l(t('!id', array('!id' => $person->nid)), t('node/!id', array('!id' => $person->nid))), + t('!first !last', array('!first' => ucwords($person->booking_firstname), '!last' => ucwords($person->booking_lastname))), + t('!email', array('!email' => $person->booking_email)), + t('!payment', array('!payment' => $person->booking_amount_paid)), + t('!payment', array('!payment' => $person->booking_total_pay_reqd)), + ); + $total_paid += $person->booking_amount_paid; + + if ($person->booking_status == 0) + $notpaid_counter++; + elseif ($person->booking_status == 1) + $bookedin_counter++; + elseif ($person->booking_status == 2) + $waiting_counter++; + } + +/* + return array( + 'first_para' => array( + '#type' => 'markup', + '#markup' => t("

The following table presents a summary"), + ), + 'table' => theme('table', array( + 'header' => $header, + 'rows' => $rows, + )), + + );*/ + + $output .= t("

The following table presents a summary of payments that have been made for !event.

", array('!event' => $event->booking_eventname)); + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + $output .= t("

Total of !bookedin registrations currently booked in, !waiting on waiting list, and !notpaid haven't paid.

", + array('!bookedin' => $bookedin_counter, '!waiting' => $waiting_counter, '!notpaid' => $notpaid_counter)); + $output .= t("

Total amount paid: $!paid

", array('!paid' => $total_paid)); + return $output; +} + +/** + * List the contents of the payments table + */ +function booking_report_paypal_payments() { + global $event; + $text = ""; + $output = ""; + $bookedin_counter = 0; + $total_paid = 0; + $total_fees = 0; + + $header = array('Node Id', 'Name', 'Email', 'Payment Date', 'Gross Payment', 'Currency', + 'Paypal Fee', 'Invoice', 'Payment Status', 'Payer ID', 'Item Name', 'IPN track ID'); + $rows = array(); + + //fetch the payment table + $query = db_select('booking_payment', 'pa') + ->condition('pa.booking_eventid', $event->eid,'=') + ->fields('pa'); + $result = $query->execute(); + + //$result = db_query("SELECT * FROM {booking_person} p WHERE p.booking_event_id = :eid", + // array(':eid' => $event->eid)); + + foreach ($result as $person) { + $rows[] = array( + l(t('!id', array('!id' => $person->booking_person_nid)), t('node/!id', array('!id' => $person->booking_person_nid))), + t('!first !last', array('!first' => ucwords($person->booking_first_name), '!last' => ucwords($person->booking_last_name))), + t('!email', array('!email' => $person->booking_buyer_email)), + t(_booking_convert_ts($person->booking_payment_date)->format('j F, Y H:i')), + t('!payment', array('!payment' => $person->booking_mc_gross)), + t('!currency', array('!currency' => $person->booking_mc_currency)), + t('!fee', array('!fee' => $person->booking_mc_fee)), + t('!invoice', array('!invoice' => $person->booking_invoice)), + t($person->booking_payment_status), + t($person->booking_payer_id), + t($person->booking_item_name), + t($person->booking_ipn_track_id) + ); + $total_paid += $person->booking_mc_gross; + $total_fees += $person->booking_mc_fee; + } + + $output .= t("

The following table presents payment entries from paypal and manual payments that have been made for !event.

", array('!event' => $event->booking_eventname)); + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + $output .= t("

Gross amount paid: $!paid. Total amount of fees paid: $!fees

", array('!paid' => $total_paid, '!fees' => $total_fees)); + return $output; +} + + +function booking_coming_page() { + global $event; + $output = ""; + $table = ""; + //$header = array('Name', 'Occupation', 'State'); + $header = array('Name', 'State'); + $booking_limit = variable_get('booking_regn_limit','350'); + $rows = array(); + + if (variable_get('booking_auto_show_on_lists', 1) == 1) + { + $or = db_or()->condition('p.booking_status', 0)->condition('p.booking_status', 1); + + $result = db_select('booking_person', 'p') + ->fields('p', array('booking_firstname', 'booking_lastname', 'booking_state', 'booking_readinggroup', 'booking_country')) + ->condition($or) + ->condition('p.booking_event_id', $event->eid, '=') + ->orderBy('booking_country') + ->orderBy('booking_state') + ->orderBy('booking_lastname') + ->orderBy('booking_firstname') + ->execute(); + + } + else + { + $result = db_select('booking_person', 'p') + ->fields('p', array('booking_firstname', 'booking_lastname', 'booking_state', 'booking_readinggroup', 'booking_country')) + ->condition('p.booking_status', 1) + ->condition('p.booking_event_id', $event->eid, '=') + ->orderBy('booking_country') + ->orderBy('booking_state') + ->orderBy('booking_lastname') + ->orderBy('booking_firstname') + ->execute(); + +/* + $result = db_query('SELECT booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country + FROM ( + SELECT booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country + FROM {booking_person} + WHERE booking_status = 1 and booking_event_id = :eid + ) AS booking + ORDER BY booking_state, booking_lastname, booking_firstname', + array(':eid' => $event->eid)); + */ + + } + + //while ($booking = db_fetch_object($result)) { + + //watchdog('booking', "Who's coming query: @info", array('@info' => var_export($result, TRUE))); + + foreach ($result as $person) { + $rows[] = array( + t('!first !last', array('!first' => ucwords($person->booking_firstname), + '!last' => ucwords($person->booking_lastname))), + //only for when we have readings groups + //t('!group',array('!group' => $person->booking_readinggroup)), + t('!state', array('!state' => ($person->booking_country === variable_get('booking_default_country')) ? $person->booking_state : $person->booking_country)), + ); + } + + //watchdog('booking', "Who's coming formatted: @info", array('@info' => var_export($rows, TRUE))); + + //output the results + //check there were some bookings + if (count($rows) > 0) + { + if (count($rows) >= $booking_limit) + { + //there is a waiting list + $output .= token_replace(variable_get('booking_whoscoming_pre_waitlist_text'), booking_define_tokens()); + } + else + { + //there's no waiting list + $output .= token_replace(variable_get('booking_whoscoming_pre_text'), booking_define_tokens()); + } + + //theme the table of registrations + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + } + else + { + //no bookings + $output .= token_replace(variable_get('booking_whoscoming_pre_noregistrations_text'), booking_define_tokens()); + } + + //include any post-text + $output .= token_replace(variable_get('booking_whoscoming_post_text'), booking_define_tokens()); + + return $output; +} + +function booking_waitinglist_page() { + global $event; + $output = ""; + $table = ""; + $count = 1; + //$header = array('Name', 'Occupation', 'State'); + $header = array('Name', 'State', 'Position'); + $booking_limit = variable_get('booking_regn_limit','350'); + $rows = array(); + + $result = db_query('SELECT DISTINCT nid, booking_firstname, booking_lastname, booking_state, booking_readinggroup + FROM ( + SELECT p.nid, p.booking_firstname, p.booking_lastname, p.booking_state, p.booking_readinggroup, pay.booking_payment_date + FROM {booking_person} p, {booking_payment} pay + WHERE booking_status = 2 and booking_event_id = :eid and p.nid = pay.booking_person_nid + ) AS booking + ORDER BY booking_payment_date', + array(':eid' => $event->eid)); + + //watchdog('booking', "Who's coming query: @info", array('@info' => var_export($result, TRUE))); + + foreach ($result as $person) { + $rows[] = array( + t('!first !last', array('!first' => ucwords($person->booking_firstname), + '!last' => ucwords($person->booking_lastname))), + //only for when we have readings groups + //t('!group',array('!group' => $person->booking_readinggroup)), + t('!state', array('!state' => $person->booking_state)), + t($count++), + ); + } + //watchdog('booking', "Who's coming formatted: @info", array('@info' => var_export($rows, TRUE))); + + + //output the results + //check there were people on the waiting list + if (count($rows) > 0) + { + //include the pre-text + $output .= token_replace(variable_get('booking_waitingpage_pre_text'), booking_define_tokens()); + + //theme the table of waiting list people + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + } + else + { + //no one on the waiting list + $output .= token_replace(variable_get('booking_waitingpage_pre_nowaitlist_text'), booking_define_tokens()); + } + + //include any post-text + $output .= token_replace(variable_get('booking_waitingpage_post_text'), booking_define_tokens()); + + return $output; +} + +/** + * Generate a CSV file as a report of all current registrations + */ + +function booking_csv_report() { + global $event; + $name = 'bookings-' . format_date(time(), 'custom', 'Y-m-d-His'); + $filename = file_directory_temp() . '/' . $name; + + $delimiter = ','; + $enclosure = '"'; + $encloseAll = true; + $nullToMysqlNull = true; + $delimiter_esc = preg_quote($delimiter, '/'); + $enclosure_esc = preg_quote($enclosure, '/'); + + $fields_to_skip = array('booking_payment_id', 'booking_event_id', 'booking_tempid', 'booking_shirt_size'); + + //query the db + $query = db_select('booking_person', 'p'); + $query->join('booking_price', 'pr', 'p.booking_payment_id = pr.pid'); + $query->condition('p.booking_event_id', $event->eid) + ->fields('p') + ->fields('pr', array('booking_price', 'booking_price_descrip')); + $result = $query->execute()->fetchAll(); + + //open the filehandle + $handle = @fopen($filename, 'w'); + + //write the header based on the first result + $header_array = array(); + foreach ($result[0] as $key => $value) + { + if (in_array($key, $fields_to_skip)) + continue; + $header_array[] = $key; + } + + $header = implode( $delimiter, $header_array ); + //watchdog('booking', "CSV header: @info", array('@info' => var_export($header_array, TRUE))); + @fwrite($handle, $header . "\n"); + + //each record + foreach ($result as $record) { + + $output = array(); + //each keypair in the record + foreach ($record as $key => $value) + { + //fields to skip + if (in_array($key, $fields_to_skip)) + continue; + + //check for null + if ($value === NULL && $nullToMysqlNull) { + $output[] = 'NULL'; + continue; + } + + //handle dates + if ($key == 'booking_dob' || $key == 'booking_passport_expiry_date') { + $output[] = format_date($value, 'custom', 'd/m/Y'); + continue; + } + + //handle more exact dates + if ($key == 'booking_timestamp') { + $output[] = format_date($value, 'custom', 'd/m/Y H:i'); + continue; + } + + //booking status + if ($key == 'booking_status') { + $output[] = _booking_status_generate($value); + continue; + } + + // Enclose fields containing $delimiter, $enclosure or whitespace + if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $value ) ) { + $output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $value) . $enclosure; + } + else { + $output[] = $field; + } + } + $row = implode($delimiter, $output) . "\n"; + + + //watchdog('booking', "Report filename: " . $filename . "."); + /* + + //$header = "Barcode,Timestamp,First Name,Last Name,Gender,Date of Birth,Street,Suburb,Postcode,State,Country,Home Phone Number,Mobile Phone Number,Email,Second Email,Ecclesia,Baptised,Married,Partner Name,Room Mate 1,Room Mate 2,Help Areas,Attending Post Conference,Payment Method,Deposit Payment Deadline,Amount Paid,Discount,Status,T-shirt size"; + $header = "First Name,Last Name,Gender,Date of Birth,Married,Partner Name,Email Address,Mobile Phone,Home Phone,Baptised,"; + + if (variable_get('booking_enable_passport', 1) == 1) + $header .= "Passport Number,Passport Expiry,Passport Issue Name,Passport Issue Location,"; + + if (variable_get('booking_enable_tshirts', 0) == 1) + $header .= "T-Shirt size,"; + + $header .= "Ecclesia,Street,Suburb,Post Code,State,Country,Emergency Contact Name,Emergency Contact Type,Emergency Contact Phone," . + "Emergency Contact Phone Alt,Medicare Number,Help Reading,Help Chairing,Help Music,Dietary Requirements,First Aid,Nurse," . + "Booking Status,Date Paid,Amount Due,Amount Paid"; + + if (variable_get('booking_enable_skills', 1) == 1) + $header .= ",Building Skills,Cooking Skills,Child Minding Skills,Other Languages,Mission Experience"; + + $query = db_query("SELECT * FROM {booking_person} p WHERE p.booking_event_id = :eid", + array(':eid' => $event->eid)); + $result = $query->fetchAll(); + + $music_help = empty($r->booking_help_music) ? '' : $r->booking_help_music; + $row = ucwords($r->booking_firstname) . ',' . ucwords($r->booking_lastname) . ',' . $r->booking_gender . ',' . format_date($r->booking_dob, 'custom', 'd/m/Y') . ',' . + $r->booking_married . ',' . $r->booking_partner_name . ',' . $r->booking_email . ',"' . $r->booking_mobile . '","' . $r->booking_phone . '",' . + $r->booking_baptised . ','; + + if (variable_get('booking_enable_passport', 1) == 1) + $row .= $r->booking_passport_num . ',' . + + $row .= '"' . $r->booking_ecclesia . '","' . $r->booking_street . '","' . $r->booking_suburb . '",' . $r->booking_postcode . ',' . + $r->booking_state . ',' . $r->booking_country . ',"' . + $r->booking_guardian_name . '",' . $r->booking_guardian_type . ',"' . $r->booking_guardian_phone . '","' . $r->booking_guardian_phone_alt . '",' . + $r->booking_medicare . ',' . + $r->booking_help_reading . ',' . $r->booking_help_chairing . ',"' . $music_help . '","' . + $r->booking_dietary . '",' . $r->booking_firstaid . ',' . $r->booking_nurse . ',' . + _booking_status_generate($r->booking_status) . ',' . format_date(_booking_datepaid_ts($r->nid), 'custom', 'd/m/Y H:i') . ',' . + $r->booking_total_pay_reqd . ',' . $r->booking_amount_paid . "\n"; +*/ + + @fwrite($handle, $row); + //$index++; + } + + @fclose($handle); + + drupal_add_http_header("Content-type", "application/octet-stream; charset=utf-8"); + drupal_add_http_header("Content-Disposition", "attachment; filename=" . $name . ".csv"); + + @readfile($filename); + @unlink($filename); + exit(0); +} \ No newline at end of file diff --git a/booking.tokens.inc b/booking.tokens.inc new file mode 100644 index 0000000..e386b55 --- /dev/null +++ b/booking.tokens.inc @@ -0,0 +1,567 @@ + ' ', + 'format' => filter_default_format(), + ); + + $form = array (); + $default_aims_and_rules_text = "

During [booking:eventname] we ask that you consider the following so that each of us can be free from distraction whilst we grow in Christ together. Christ is our ultimate example so in all actions, thoughts and words we ask that you demonstrate behaviour that emulates him.

\n" . + ""; + $default_into_regn_not_opened_text = t("


Hi. Welcome to the booking page for [booking:eventname], God willing.

\n" . + "

Bookings are not yet open. Please try again later.

" . + "

If you have any questions, please use the !contact form.

", + array('!contact' => l('contact us', 'contact-us'))); + $default_into_regn_closed_text = t("


Hi. Welcome to the booking page for [booking:eventname], God willing.

\n" . + "

Bookings for this event are now closed.

" . + "

If you have any questions, please use the !contact form.

", + array('!contact' => l('contact us', 'contact-us'))); + $default_intro_text = "


Hi. Welcome to the booking page for [booking:eventname], God willing.

\n" . + "

So we can make sure this event is tailored for you, can you please complete ALL of the following details with the correct information.
\n" . + "Upon completing the form we will provide the necessary information to pay for [booking:eventname].

 

"; + $waiting_intro_text = "

Hi. Welcome to the booking page for [booking:eventname], God willing.

" . + "

We have reached the maximum capacity that the venue can hold, so all bookings are now going directly onto the waiting list.

" . + "

If you would still like to book into the waiting list, please complete ALL of the following details with the correct information and make the necessary payment." . + "Upon completing the form we will provide the necessary information to pay for [booking:eventname].

 

"; + + $booking_whoscoming_pre_text = "

The following people are registered to attend [booking:eventname]. Registrations are limited so be sure to get in early!

\n
\n"; + $booking_whoscoming_pre_waitlist_text = "

The following people are registered to attend [booking:eventname]. Registrations are limited so be sure to get in early!

\n
\n" . + "

Even though our registrations have reached maximum capacity, you can still register to join the waiting list." . + " See how many people are on the waiting list here.

\n
\n"; + $booking_whoscoming_pre_noregistrations_text = "

Nobody is coming, because nobody has booked in yet!

\n"; + $booking_whoscoming_post_text = "

\n"; + $booking_waitingpage_pre_text = "

The following people are on the waiting list to attend [booking:eventname]. " . + "Even though our registrations have reached maximum capacity, you can still register to join the waiting list.

\n
\n"; + $booking_waitingpage_pre_nowaitlist_text = "

There's no one on the waiting list yet. If you haven't already done so, go ahead and register.

\n
\n"; + $booking_waitingpage_post_text = "

\n"; + + $default_email_text = "Dear [booking:fname],\n" . + "Congratulations, you are officially booked into [booking:eventname]. " . + "Your registration reference number is [booking:booking-id].\n" . + "Please don't hesitate to contact us if you have any queries by replying to this email. " . + "We look forward to seeing you (God Willing) at [booking:eventname]!\n" . + "Love in Jesus,\n[booking:eventname] Registrations Team\n" . + "________________________________________________________\n" . + "The following information shows the details you entered when you registered. " . + "If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" . + "________________________________________________________"; + $booking_email_regn_complete_text = "Dear [booking:fname],\n" . + "Thank-you for completing your payment for [booking:eventname].\n" . + "Please don't hesitate to contact us if you have any queries by replying to this email. " . + "We look forward to seeing you (God Willing) at [booking:eventname]!\n" . + "Love in Jesus,\n[booking:eventname] Registrations Team\n" . + "________________________________________________________\n" . + "The following information shows the details you entered when you registered. " . + "If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" . + "________________________________________________________"; + $booking_email_waitinglist_text = "Dear [booking:fname],\n" . + "Thank-you for registering to attend [booking:eventname]. Unfortunately the venue for this event is full, and you have been placed on the waiting list to attend.\n" . + "We will contact you if a position becomes available for you. Please don't hesitate to contact us if you have any queries by replying to this email.\n" . + "Love in Jesus,\n[booking:eventname] Registrations Team\n" . + "________________________________________________________\n" . + "The following information shows the details you entered when you registered. " . + "If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" . + "________________________________________________________"; + $booking_email_paymentoutstanding_text = "Dear [booking:fname],\n" . + "Thank-you for registering to attend [booking:eventname]. Our records indicate that you currently have $[booking:payment-required] outstanding to finalise your registration.\n" . + "Please visit [booking:balance-payment-link] in order to make your final payment.\n" . + "Love in Jesus,\n[booking:eventname] Registrations Team\n" . + "________________________________________________________\n"; + $booking_email_waitinglistpromotion = "Dear [booking:fname],\n" . + "We have some great news for you. A place at [booking:eventname] for you has just become available. " . + "If you wish to secure your place at [booking:eventname], please visit [booking:balance-payment-link] to make your final payment. " . + "Our records indicate that you currently have $[booking:paypal-total-amount] outstanding (including Paypal transaction fees).\n" . + "Once we have received your payment, you will be sent an automatic confirmation email thanking you for paying your outstanding fees. " . + "If you are paying via Paypal's eCheque feature, please be aware that payments take 3-5 working days to clear, " . + "and you will not receive the confirmation email until that has occurred.\n" . + "Please don't hesitate to contact us if you have any queries by replying to this email. We look forward to seeing you, God Willing, at [booking:eventname]\n" . + "Love in Jesus,\n[booking:eventname] Registrations Team."; + + $booking_confirmation_text = "

Thanks for filling out the registration form.

\n" . + "

To complete your booking, please make a payment of $[booking:payment-required] into the following bank account
\n" . + " Account Name: blah
\n BSB: blah
\n Account Number: blah

\n" . + "

Use the following as the transaction description:
[booking:payment-transaction-desc]

" . + "

Alternatively, you can pay by a cheque payable to blah. Please post the cheque to
Address

\n"; + $booking_confirmation_waitinglist_text = "

Thanks for filling out the registration form.

\n" . + "

Although you are on the waiting list, you can make a refundable payment of $[booking:payment-required] into the following bank account
\n" . + " Account Name: blah
\n BSB: blah
\n Account Number: blah

\n" . + "

Use the following as the transaction description:
[booking:payment-transaction-desc]

" . + "

Alternatively, you can pay by a cheque payable to blah. Please post the cheque to
Address

\n"; + $booking_regn_confirm_married_text = "

In your registration details, you indicated that you were married. Please note that both you and your spouse must book in and pay indivdually.

"; + + $form['tokens'] = array( + '#theme' => 'token_tree', + '#token_types' => array('booking'), + ); + $form['registration'] = array( + '#type' => 'fieldset', + '#title' => 'Registration Page Text Definitions', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['registration']['default_into_regn_not_opened_text'] = array( + '#title' => t('Text to use at the start of the registration form if registrations haven\'t opened yet'), + '#description' => t(''), + '#type' => 'textarea', + '#default_value' => variable_get('default_into_regn_not_opened_text', $default_into_regn_not_opened_text), + ); + /* + $booking_registration_intro_text = variable_get('booking_registration_intro_text', array('value' => '', 'format' => NULL)); + $form['registration']['booking_registration_intro_text'] = array( + '#title' => t('Text to use at the start of the registration form'), + '#type' => 'text_format', + '#format' => isset($edit['format']) ? $edit['format'] : NULL, + '#description' => t(''), + '#default_value' => $booking_registration_intro_text['value'], + ); + */ + +/* +$booking_registration_intro_text = variable_get('booking_registration_intro_text', $defaults); +*/ + $form['registration']['booking_registration_intro_text'] = array( + '#title' => t('Text to use at the start of the registration form'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_registration_intro_text', $default_intro_text), + //'#type' => 'text_format', + //'#format' => 'full_html', + //'#default_value' => $booking_registration_intro_text['value'], + ); + + $form['registration']['booking_registration_waiting_intro_text'] = array( + '#title' => t('Text to use at the start of the registration form if the venue has reached capacity'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_registration_waiting_intro_text', $waiting_intro_text), + ); + $form['registration']['default_into_regn_closed_text'] = array( + '#title' => t('Text to use at the start of the registration form if registrations have closed'), + '#description' => t(''), + '#type' => 'textarea', + '#default_value' => variable_get('default_into_regn_closed_text', $default_into_regn_closed_text), + ); + $form['registration']['booking_registration_aims_rules_text'] = array( + '#title' => t('The aims and rules attendees must agree to'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_registration_aims_rules_text', $default_aims_and_rules_text), + ); + /*Text for the confirmation page*/ + $form['confirmation'] = array( + '#type' => 'fieldset', + '#title' => 'Confirmation Page Text Definitions', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['confirmation']['booking_regn_confirm_page'] = array( + '#title' => t('Text to use on the confirmation page if the person has booked in and is not on the waiting list'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_regn_confirm_page', $booking_confirmation_text), + ); + $form['confirmation']['booking_regn_confirm_waiting_page'] = array( + '#title' => t('Text to use on the confirmation page if the person is on the waiting list'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_regn_confirm_waiting_page', $booking_confirmation_waitinglist_text), + ); + $form['confirmation']['booking_regn_confirm_married_text'] = array( + '#title' => t('Optional text to add to the confirmaton page if the person indicated they were married.'), + '#type' => 'textarea', + '#rows' => 1, + '#description' => t(''), + '#default_value' => variable_get('booking_regn_confirm_married_text', $booking_regn_confirm_married_text), + ); + + /*Text for the balance payment page*/ + $form['balance'] = array( + '#type' => 'fieldset', + '#title' => 'Balance Payment Page Text Definitions', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + //$booking_regn_balance_page_paid = variable_get('booking_regn_balance_page_paid', $defaults); + $form['balance']['booking_regn_balance_page_paid'] = array( + '#title' => t('Text to use on the balance payment page if registration is fully paid.'), + '#type' => 'textarea', + '#default_value' => variable_get('booking_regn_balance_page_paid', ''), + '#description' => t(''), + //'#type' => 'text_format', + //'#format' => 'full_html', + //'#default_value' => $booking_regn_balance_page_paid['value'], + ); + + //$booking_regn_balance_page = variable_get('booking_regn_balance_page',$defaults); + $form['balance']['booking_regn_balance_page'] = array( + '#title' => t('Text to use on the balance payment page.'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_regn_balance_page', ''), + //'#type' => 'text_format', + //'#format' => 'full_html', + //'#default_value' => $booking_regn_balance_page['value'], + ); + //$booking_regn_balance_married_text = variable_get('booking_regn_balance_married_text', $defaults); + $form['balance']['booking_regn_balance_married_text'] = array( + '#title' => t('Optional text to add to the balance payment page if the person indicated they were married.'), + '#type' => 'textarea', + '#rows' => 1, + '#description' => t(''), + '#default_value' => variable_get('booking_regn_balance_married_text', ''), + //'#type' => 'text_format', + //'#format' => 'full_html', + //'#default_value' => $booking_regn_balance_married_text['value'], + ); + + /*People reporting pages*/ + $form['people_lists'] = array( + '#type' => 'fieldset', + '#title' => 'Who\'s Coming and Waiting List Page Text Definitions', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + /*Text for the Who's coming page*/ + $form['people_lists']['booking_whoscoming_pre_noregistrations_text'] = array( + '#title' => t('Text to use at the start of the Who\'s Coming page if there are no registrations'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_whoscoming_pre_noregistrations_text', $booking_whoscoming_pre_noregistrations_text), + ); + $form['people_lists']['booking_whoscoming_pre_text'] = array( + '#title' => t('Text to use at the start of the Who\'s Coming page if there is no waiting list'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_whoscoming_pre_text', $booking_whoscoming_pre_text), + ); + $form['people_lists']['booking_whoscoming_pre_waitlist_text'] = array( + '#title' => t('Text to use at the start of the Who\'s Coming page if there is a waiting list'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_whoscoming_pre_waitlist_text', $booking_whoscoming_pre_waitlist_text), + ); + $form['people_lists']['booking_whoscoming_post_text'] = array( + '#title' => t('Text to use at the end of the Who\'s Coming page'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_whoscoming_post_text', $booking_whoscoming_post_text), + ); + + /*Text for the Waiting List page*/ + $form['people_lists']['booking_waitingpage_pre_text'] = array( + '#title' => t('Text to use at the start of the Waiting List page'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_waitingpage_pre_text', $booking_waitingpage_pre_text), + ); + $form['people_lists']['booking_waitingpage_pre_nowaitlist_text'] = array( + '#title' => t('Text to use at the start of the Waiting List page if there is no-one on the waiting list yet'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_waitingpage_pre_nowaitlist_text', $booking_waitingpage_pre_nowaitlist_text), + ); + $form['people_lists']['booking_waitingpage_post_text'] = array( + '#title' => t('Text to use at the end of the Waiting List page'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_waitingpage_post_text', $booking_waitingpage_post_text), + ); + + /*Text for emails*/ + $form['emails'] = array( + '#type' => 'fieldset', + '#title' => 'Email Text Definitions', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['emails']['booking_email_bookedin_text'] = array( + '#title' => t('Text to use in an email indicating the person has booked in and is not on the waiting list'), + '#type' => 'textarea', + //'#format' => 'full_html', + '#description' => t(''), + '#default_value' => variable_get('booking_email_bookedin_text', $default_email_text), + ); + $form['emails']['booking_email_regn_complete_text'] = array( + '#title' => t('Email text to indicate a person has completed the payment for their booking'), + '#type' => 'textarea', + //'#format' => 'full_html', + '#description' => t(''), + '#default_value' => variable_get('booking_email_regn_complete_text', $booking_email_regn_complete_text), + ); + $form['emails']['booking_email_waitinglist_text'] = array( + '#title' => t('Email text to indicate a person has registered but is on the waiting list'), + '#type' => 'textarea', + //'#format' => 'full_html', + '#description' => t(''), + '#default_value' => variable_get('booking_email_waitinglist_text', $booking_email_waitinglist_text), + ); + $form['emails']['booking_email_paymentoutstanding_text'] = array( + '#title' => t('Email text to send a person reminding them of how much they owe'), + '#type' => 'textarea', + //'#format' => 'full_html', + '#description' => t(''), + '#default_value' => variable_get('booking_email_paymentoutstanding_text', $booking_email_paymentoutstanding_text), + ); + $form['emails']['booking_email_waitinglistpromotion'] = array( + '#title' => t('Email text to send a person on the waiting list when a spot opens up for them'), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get('booking_email_waitinglistpromotion', $booking_email_waitinglistpromotion), + ); + + //add a bunch of custom emails + for ($i = 1; $i <= CUSTOM_EMAIL_COUNT; $i++) + { + $subject_fieldname = 'booking_email_subject_custom' . $i; + $body_fieldname = 'booking_email_custom' . $i; + $form['emails'][$subject_fieldname] = array ( + '#type' => 'textfield', + '#title' => t('Subject line for Custom Email ' . $i), + '#size' => 150, + '#maxlength' => 300, + '#default_value' => variable_get($subject_fieldname,'[booking:eventname]'), + ); + $form['emails'][$body_fieldname] = array( + '#title' => t('Email text for custom email ' . $i), + '#type' => 'textarea', + '#description' => t(''), + '#default_value' => variable_get($body_fieldname, ''), + ); + + } + + //see http://drupal.org/node/820816#comment-3100356 + //and http://drupal.org/node/823362 + /* + $booking_email_test_text = variable_get('booking_email_test_text', array('value' => '', 'format' => NULL)); + $form['booking_email_test_text'] = array( + '#title' => t('Test email text'), + '#type' => 'text_format', + '#format' => isset($edit['format']) ? $edit['format'] : NULL, + '#description' => t(''), + '#default_value' => $booking_email_test_text['value'], + ); + */ + + return system_settings_form($form, FALSE); +} + +function booking_tokens_admin_validate($form, $form_state) { + +} +/** + * Provide information about our custom placeholder/token. + * + * @see http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_token_info/7 + * @see http://api.lullabot.com/token_example_token_info/7 + * @return array + * An associative array of available tokens and token types. + */ +function booking_token_info() { + + $info['types']['booking'] = array( + 'name' => t('Booking Tokens'), + 'description' => t('Tokens related to bookings module.'), + 'needs-data' => 'booking', + ); + $info['tokens']['booking']['eventname'] = array( + 'name' => t('Event Name'), + 'description' => t('Name of the current event.') + ); + $info['tokens']['booking']['regn-count'] = array( + 'name' => t('Registration Count'), + 'description' => t('Number of people registered for the current event.') + ); + $info['tokens']['booking']['regn-max'] = array( + 'name' => t('Registration Limit'), + 'description' => t('Maximum allowed number of people for the current event.') + ); + $info['tokens']['booking']['contact-email'] = array( + 'name' => t('Event Contact Email'), + 'description' => t('Contact Address for the current event.') + ); + $info['tokens']['booking']['eventdates'] = array( + 'name' => t('Event Dates'), + 'description' => t('Dates of the current event.') + ); + $info['tokens']['booking']['fname'] = array( + 'name' => t('First Name'), + 'description' => t('First Name of the attendee.') + ); + $info['tokens']['booking']['lname'] = array( + 'name' => t('Last Name'), + 'description' => t('Last Name of the attendee.') + ); + $info['tokens']['booking']['dietary'] = array( + 'name' => t('Dietary Requirements'), + 'description' => t('Specified dietary requirements of the attendee') + ); + $info['tokens']['booking']['payment-required'] = array( + 'name' => t('Payment Required'), + 'description' => t('The total amount required to complete the registration.') + ); + $info['tokens']['booking']['balance-payment-link'] = array( + 'name' => t('Balance Payment Link'), + 'description' => t('If using paypal, the link to the balance payment page.') + ); + $info['tokens']['booking']['confirm-payment-link'] = array( + 'name' => t('Confirm Payment Link'), + 'description' => t('If using paypal, the link to the booking confirmation page to complete a registration.') + ); + $info['tokens']['booking']['paypal-deposit-amount'] = array( + 'name' => t('Paypal Deposit Only'), + 'description' => t('The deposit amount required to confirm the registration including paypal fees.') + ); + $info['tokens']['booking']['paypal-total-amount'] = array( + 'name' => t('Paypal Outstanding Balance'), + 'description' => t('The total amount required to complete the registration including paypal fees.') + ); + $info['tokens']['booking']['paypal-deposit-form'] = array( + 'name' => t('Paypal Deposit Form Button'), + 'description' => t('The paypal form for the deposit amount.') + ); + $info['tokens']['booking']['paypal-total-form'] = array( + 'name' => t('Paypal Total Form Button'), + 'description' => t('The paypal form for the total amount.') + ); + $info['tokens']['booking']['booking-id'] = array( + 'name' => t('Booking ID'), + 'description' => t('ID of the user\'s registration.') + ); + $info['tokens']['booking']['waitinglist-position'] = array( + 'name' => t('Waiting List Position'), + 'description' => t('Position of the registrant on the waiting list.') + ); + $info['tokens']['booking']['payment-transaction-desc'] = array( + 'name' => t('Transaction Decsription'), + 'description' => t('Text description to use for a direct deposit transaction.') + ); + $info['tokens']['booking']['regn-summary'] = array( + 'name' => t('Registration Summary'), + 'description' => t('Summary of details from user registration.') + ); + return $info; +} + +/** + * Provide replacement values for placeholder tokens. + * + * @see http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_tokens/7 + * @see http://api.lullabot.com/token_example_tokens/7 + * @param string $type + * The machine-readable name of the type (group) of token being replaced, such + * as 'node', 'user', or another type defined by a hook_token_info() + * implementation. + * @param array $tokens + * An array of tokens to be replaced. The keys are the machine-readable token + * names, and the values are the raw [type:token] strings that appeared in the + * original text. + * @param array $data (optional) + * An associative array of data objects to be used when generating replacement + * values, as supplied in the $data parameter to token_replace(). + * @param array $options (optional) + * An associative array of options for token replacement; see token_replace() + * for possible values. + * @return array + * An associative array of replacement values, keyed by the raw [type:token] + * strings from the original text. + */ +function booking_tokens($type, $tokens, array $data = array(), array $options = array()) { + + //watchdog('booking', 'Processing token request'); + + $replacements = array(); + $sanitize = !empty($options['sanitize']); + if ($type == 'booking') { + foreach ($tokens as $name => $original) { + if (array_key_exists($name, $data)) { + $replacements[$original] = $data[$name]; + } + } + } + return $replacements; +} + +function booking_define_tokens() +{ + global $event; + + $booking_times = db_query("SELECT booking_event_start, booking_event_end FROM {booking_event} where eid = :eid", + array(':eid' => $event->eid))->fetchObject(); + + $regncount_query = db_query("SELECT count(*) as num_ppl FROM {booking_person} where booking_event_id = :eventid and booking_status = 1", + array(':eventid' => $event->eid)) + ->fetchObject(); + + $tokens = array(); + $tokens['eventname'] = $event->booking_eventname; + $tokens['eventdates'] = _date_range_to_string(date("Y-m-d", $booking_times->booking_event_start), + date("Y-m-d", $booking_times->booking_event_end)); + $tokens['contact-us'] = l('contact us', 'contact-us'); + $tokens['contact-email'] = variable_get('booking_contact_email'); + $tokens['regn-count'] = $regncount_query->num_ppl; + $tokens['regn-limit'] = variable_get('booking_regn_limit',0); + return $tokens; +} + + +function booking_define_personspecific_tokens($node) +{ + global $event; + $amount_paid = 0; + + //get a count of the total number of people booked in to this event + //but don't include people who haven't paid or have withdrawn their booking + $result = db_query("SELECT count(*) as num_ppl FROM {booking_person} where booking_event_id = :eventid and (booking_status = 1 or booking_status = 2)", + array(':eventid' => $event->eid)) + ->fetchObject(); + + //calcalate a new temp id to be configured for this user if required + if ($node->booking_tempid == '') + { + $tempid = _booking_uuidSecure(); + //update the user with this tempid + db_update('booking_person') + ->fields(array( + 'booking_tempid' => $tempid + )) + ->condition('nid', $node->nid) + ->execute(); + } + else + $tempid = $node->booking_tempid; + + //check how much has been paid by this person + $amount_paid = _booking_amount_paid($node->nid); + + //generate the tokens + $tokens = array(); + $tokens['eventname'] = $event->booking_eventname; + $tokens['contact-email'] = variable_get('booking_contact_email'); + $tokens['fname'] = ucwords(trim($node->booking_firstname)); + $tokens['lname'] = ucwords(trim($node->booking_lastname)); + $tokens['dietary'] = ucwords(trim($node->booking_dietary)); + $tokens['booking-id'] = $node->nid; + $tokens['payment-required'] = $node->booking_total_pay_reqd - $amount_paid; + $tokens['waitinglist-position'] = $result->num_ppl - variable_get('booking_regn_limit',350) + 1; + $tokens['payment-transaction-desc'] = $node->nid . ' ' . $node->booking_lastname; + $tokens['balance-payment-link'] = url('balance/' . $tempid, array('absolute' => TRUE)); + $tokens['confirm-payment-link'] = url('confirm/' . $tempid, array('absolute' => TRUE)); + $tokens['paypal-total-amount'] = _booking_amount_owing($node->nid, $amount_paid); + $tokens['paypal-deposit-amount'] = _booking_deposit_amount(); + $tokens['regn-summary'] = _booking_details_email_summary($node); + return $tokens; +} \ No newline at end of file diff --git a/booking.variety.inc b/booking.variety.inc new file mode 100644 index 0000000..49fa524 --- /dev/null +++ b/booking.variety.inc @@ -0,0 +1,227 @@ +!link

", + array ('!link' => l('Add New Event', 'admin/config/booking/variety/create'))); + + $header = array ( + 'tid' => t('Event ID'), + 'booking_variety_time_descrip' => t('Description'), + 'booking_variety_status' => t('Status'), + 'booking_variety_start' => t('Session Start'), + 'booking_variety_end' => t('Session End'), + 'booking_edit' => t('Edit event'), + ); + + $result = db_query("SELECT * from {booking_variety_times}"); + + foreach($result as $data) + { + $options[$data->tid] = array + ( + 'tid' => $data->tid, + 'booking_variety_time_descrip' => $data->booking_variety_time_descrip, + 'booking_variety_status' => $data->booking_variety_status, + 'booking_variety_start' => date("Y-m-d H:i", $data->booking_variety_start), + 'booking_variety_end' => date("Y-m-d H:i", $data->booking_variety_end), + 'booking_edit' => l('Edit', t('admin/config/booking/variety/!tid/edit', array('!tid' => $data->tid))), + ); + } + + $form['table'] = array ( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + '#multiple' => false, + ); + + /* + $form['submit_active'] = array + ( + '#type' => 'submit', + '#value' => t('Set Active'), + ); + */ + //watchdog('booking', 'Setting button form: @info', array ('@info' => var_export($form, TRUE))); + + return array ( + /* + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + //'#theme' => 'system_settings_form', + ), + */ + 'form' => $form, + ); +} + + +function booking_variety_admin_submit($form, &$form_state) +{ + +} + + +function booking_variety_form($node, &$form_state, $create, $editid = 0) +{ + global $event; + $form = array (); + $prefix = "

Add a new variety session timeslot for the bookings module.

"; + + if ($create == true) + { + $data = $node; + } + else + { + //verify that $editid is a number + if (! preg_match('/^[0-9]+$/', $editid)) { + drupal_set_message("Error: Invalid variety ID supplied. Unable to update variety session information.", 'error', FALSE); + drupal_goto('admin/config/booking/variety'); + return ""; + } + + $data = db_select ('booking_variety_times', 'v') + ->condition('v.tid', $editid, '=') + ->fields('v') + ->execute() + ->fetchObject(); + + $prefix = t("

Update the !event variety session details.

", array('!event' => $event->booking_eventname)); + //add this to the form in a hidden field so we can update the right event + $form['tid'] = array ( + '#type' => 'hidden', + '#value' => $editid, + ); + } + + $form['booking_variety_time_descrip'] = array ( + '#type' => 'textfield', + '#title' => t('The name of this variety session'), + '#size' => 60, + '#maxlength' => 150, + '#required' => TRUE, + '#default_value' => !empty($data->booking_variety_time_descrip) ? $data->booking_variety_time_descrip : '', + ); + + $form['booking_variety_status'] = array( + '#type' => 'checkbox', + '#title' => t('Make this variety session timeslot active'), + '#default_value' => !empty($data->booking_variety_status) ? $data->booking_variety_status : '', + ); + + $form['booking_variety_start'] = array( + '#type' => 'date_select', + '#title' => t('When will this variety session start'), + '#default_value' => empty($data->booking_variety_start) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_variety_start), + '#date_format' => 'd/m/Y H:i', + '#date_label_position' => 'within', + '#date_year_range' => '0:+5' + ); + + $form['booking_variety_end'] = array( + '#type' => 'date_select', + '#title' => t('When will this variety session end?'), + '#default_value' => empty($data->booking_variety_end) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_variety_end), + '#date_format' => 'd/m/Y H:i', + '#date_label_position' => 'within', + '#date_year_range' => '0:+5' + ); + + if ($create == true) + { + $form['submit'] = array + ( + '#type' => 'submit', + '#value' => t('Create'), + ); + } else { + $form['Update'] = array + ( + '#type' => 'submit', + '#value' => t('Update'), + ); + $form['Delete'] = array + ( + '#type' => 'submit', + '#value' => t('Delete'), + ); + } + + return array ( + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + 'form' => $form, + ); +} + +function booking_variety_form_submit($form, &$form_state) { + global $event; + $values = $form_state['input']; + + if ($form_state['values']['op'] == 'Create') + { + db_insert('booking_variety_times') + ->fields(array( + 'booking_eventid' => $event->eid, + 'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0, + 'booking_variety_time_descrip' => $values['booking_variety_time_descrip'], + 'booking_variety_start' => _datetime_array_to_ts($values['booking_variety_start']), + 'booking_variety_end' => _datetime_array_to_ts($values['booking_variety_end']), + )) + ->execute(); + } + elseif ($form_state['values']['op'] == 'Delete') + { + //verify that tid is a number + if (! preg_match('/^[0-9]+$/', $values['tid'])) { + drupal_set_message("Error: Invalid variety timeslot ID supplied. Unable to delete entry.", 'error', FALSE); + return ""; + } + + $num_deleted = db_delete('booking_variety_times') + ->condition('tid', $values['tid']) + ->execute(); + + $message = t("Successfully deleted !num row(s), corresponding to variety session timeslot '!desc'", + array('!num' => $num_deleted, '!desc' => $values['booking_variety_time_descrip'])); + drupal_set_message($message, $type = 'status'); + } + else + { + //verify that booking_eid is a number + if (! preg_match('/^[0-9]+$/', $values['tid'])) { + drupal_set_message("Error: Invalid variety session timeslot ID supplied. Unable to update entry.", 'error', FALSE); + return ""; + } + + //update the event + db_update('booking_variety_times') + ->fields(array ( + 'booking_eventid' => $event->eid, + 'booking_variety_time_descrip' => $values['booking_variety_time_descrip'], + 'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0, + 'booking_variety_start' => _datetime_array_to_ts($values['booking_variety_start']), + 'booking_variety_end' => _datetime_array_to_ts($values['booking_variety_end']), + )) + ->condition('tid', $values['tid']) + ->execute(); + } + + $form_state['redirect'] = array('admin/config/booking/variety'); +} \ No newline at end of file