<?php
// $Id$

/**
 *		@file
 *		sabreQMS Module for plugin to Drupal 7 Framework
 *
 *		Discrepancy Log function handling
 *    -> This includes Discrepancy Comments, Discrepancy Parts, and Discrepancy Files record handling
*/

//require_once('sabreQMS.utils.inc');
require_once('sabreQMS.troublecall.inc');
require_once('sabreQMS.discrepancylist.inc');
require_once('sabreQMS.simulatordownlist.inc');
require_once('sabreQMS.files.inc');
require_once('sabreQMS.drfiles.inc');
require_once('sabreQMS.drparts.inc');
require_once('sabreQMS.comments.inc');
require_once('sabreQMS.customers.inc');


/*
 *	discrepancy_form()
 *
 *  overloads:  hook_form()
 *
 *	Displays a Discrepancy Entry form to accept user input
 */


function discrepancy_form($form, $form_state, $discrepancy_id = 0, $from_trouble_call_id = 0) {


	global $base_url;

	$user_perms = (object) Null;
	$user_perms->admin = user_access('administer sabreQMS');

	$user_perms->create_discrepancy = False;
	$user_perms->edit_discrepancy = False;
	$user_perms->set_discrepancy_flags = False;
	$user_perms->close_discrepancy = False;
	$user_perms->add_discrepancy_comments = False;
	$user_perms->edit_discrepancy_comments = False;
	$user_perms->add_discrepancy_parts = False;
	$user_perms->edit_discrepancy_parts = False;
	$user_perms->add_discrepancy_files = False;
	//$user_perms->delete_discrepancy_files = False;



	if ( $discrepancy_id == 0 ) {
		$user_perms->create_discrepancy = user_access('create discrepancy');

		if ( ( $user_perms->create_discrepancy == FALSE) && ($user_perms->admin == FALSE) ) {
	    drupal_set_message( t('Unauthorized:  Permission required'), 'status');
			return $form;
	  }
	}
	else {

		$user_perms->edit_discrepancy = user_access('edit discrepancy');
		$user_perms->set_discrepancy_flags = user_access('set discrepancy flags');
		$user_perms->close_discrepancy = user_access('close discrepancy');
		$user_perms->add_discrepancy_comments = user_access('add discrepancy comments');
		$user_perms->edit_discrepancy_comments = user_access('edit discrepancy comments');
		$user_perms->add_discrepancy_parts = user_access('add discrepancy parts');
		$user_perms->edit_discrepancy_parts = user_access('edit discrepancy parts');
		$user_perms->add_discrepancy_files = user_access('add discrepancy files');
		//$user_perms->delete_discrepancy_files = user_access('delete discrepancy files');

		// user may have partial permissions for editing, i.e.  only add comments
		// check all flags, is user allowed to be on this page
		if ( 	( $user_perms->edit_discrepancy == FALSE) &&
					( $user_perms->set_discrepancy_flags == FALSE) &&
					( $user_perms->close_discrepancy == FALSE) &&
					( $user_perms->add_discrepancy_comments == FALSE) &&
					( $user_perms->edit_discrepancy_comments == FALSE) &&
					( $user_perms->add_discrepancy_parts == FALSE) &&
					( $user_perms->edit_discrepancy_parts == FALSE) &&
					( $user_perms->add_discrepancy_files == FALSE) &&
					//( $user_perms->delete_discrepancy_files == FALSE) &&
					( $user_perms->admin == FALSE)  ) {
	    drupal_set_message( t('Unauthorized:  Permission required'), 'status');
			return $form;
	  }
	}


	$discrepancy = (object) Null;
	$dr_comments = array();
	$dr_parts = array();
	$dr_files = array();
	$dr_links = array();
	$dr_no_base = '';

	$trouble_call = (object) Null;



	// javascript loaded in the after_build function
	$form['#after_build'][] = 'discrepancy_form_after_build';



	//------------------- ROUTING ---------------------------
	// determine the return routing url
	$destination = drupal_get_destination();
	$goto_url = $destination['destination'];

	if( !strlen($goto_url) || ($goto_url == current_path()) ) {
		$goto_url = 'search/discrepancy';
	}




	// NEW DR, discrepancy_id == 0, otherwise EDIT existing
	if ( $discrepancy_id == 0 ) {

		//  Determine the new DR No when submitted
		$dr_no_base = _st_generate_report_base_no('DR');

		if ( $from_trouble_call_id ) {
			// DR being created from a trouble call

			$trouble_call = _get_trouble_call($from_trouble_call_id);

			if ( (object)Null == $trouble_call ) {
				drupal_set_message( t('Trouble Call Not Found!'), 'warning');
				drupal_goto($goto_url);
				return $form;
			}

			// create a DR object just for setting up the TC link on the DR form
			// ususally this only happens for editing a DR, but this is an exceptional situation
			$temp_dr = new stdClass();
			$temp_dr->from_trouble_call_id = $from_trouble_call_id;

			$dr_links = _get_discrepancy_linked_reports($temp_dr);
		}
	}
	else {
		// discrepancy_id > 0, get the discrepancy record
		$discrepancy = _get_discrepancy($discrepancy_id);

		if ( (object)Null == $discrepancy ) {
			drupal_set_message( t('Discrepancy Not Found!'), 'warning');
			drupal_goto($goto_url);
			return $form;
		}

		// check if the discrepancy is closed -- if it is, prevent non-Admin from editing
		if ( !empty($discrepancy->date_closed) && ($user_perms->admin == False)) {
			drupal_set_message( t('Unauthorized:  Administrator permission required to edit a closed discrepancy report'), 'status');
			drupal_goto($goto_url);
			return $form;
		}

		$dr_links = _get_discrepancy_linked_reports($discrepancy, 'discrepancy/edit/' . $discrepancy_id);
	}


	//------------ BUILD FORM ------------------

	// storage field for the discrepancy_id (edit) -- hidden
	$form['discrepancy_id'] = array(
		'#type' => 'textfield',
		'#default_value' => $discrepancy_id,   // for ADD mode, this is 0
		'#attributes' => array('id' => 'qms-discrepancy-id',
													 'class' => array('qms-hidden-field')),
	);

	if ( $from_trouble_call_id ) {
		$form['from_trouble_call_id'] = array(
			'#type' => 'textfield',
			'#default_value' => $from_trouble_call_id,
			'#attributes' => array('id' => 'qms-from-trouble-call-id',
														 'class' => array('qms-hidden-field')),
		);
	}


	// DR No.  Display it, but do not allow it to be edited

	if ( $discrepancy_id == 0 ) { // NEW

		// only for display purposes -- the separately defined dr_no field is where the actual number is stored/retrieved
		// drupal can't access content from an 'item' field
		$form['dr_no_display'] = array(
			'#title' => t('DR No.'),
			'#type' =>'item',
			'#markup' => '<div class="qms-report-no">' . t($dr_no_base) . '___</div>',
			'#suffix' => '<div class="qms-desc">Assigned when submitted.</div><hr />',
		);
	}
	else {
		// only for display purposes -- the separately defined dr_no field is where the actual number is stored/retrieved
		// drupal can't access content from an 'item' field
		$form['dr_no_display'] = array(
			//'#title' => t('DR No.'),
			'#type' =>'item',
			'#markup' => '<div class="qms-report-no">' . t($discrepancy->dr_no) . '</div>',
			'#suffix' => _st_format_record_timestamp_table($discrepancy),
		);
	}

	$form['dr_no'] = array(
		'#type' =>'textfield',
		'#default_value' => ($discrepancy_id > 0 ?  t($discrepancy->dr_no) : t($dr_no_base) ),
		'#attributes' => array('class' => array('qms-hidden-field')),
	);


	//-----------------------------------------

	global $customer_list;
	global $chapter_list;
	global $tech_list;
	global $simulator_list;  // if user is linked to a customer, this list will only be sims for that customer
	global $action_list;

	global $user;
  	global $base_url;


	/*
	// ASSIGN TECHNICIAN??  Is this feature enabled allowing for the tech to be assigned when DR is created or afterward
	$assign_technician  = variable_get(QMS_VAR_ASSIGN_TECHNICIAN, 0);  // if not set, default to off
	*/

	// setup a plain table for form layout
	$form['markup_1'] = array(
		'#markup' => '<table class="qms-plain-table" style="width:100%"><tr><td style="width:40%">',
	);

	// USER IS CUSTOMER?
	$user_is_customer_id = _user_is_customer($user->uid);


	if ( $user_is_customer_id ) {
		// user is not allowed to (re)assign a technician, display only element
		// display the tech/user	as the currently logged in user for new DRs and the user on record for saved DRs
		$tech_name = '';
		if ( $discrepancy_id > 0 ) {
			$tech_name = _get_user_name($discrepancy->tech_user_id);
		}
		else if ( $from_trouble_call_id > 0 ) {
			$tech_name = _get_user_name($trouble_call->tech_user_id);
		}
		else {
			$tech_name = '[unassigned]';
		}

		$form['tech'] = array(
			'#type' => 'item',
			'#title' => t('Technician/Instructor'),
			'#markup' => $tech_name,
		);
	}
	else {
		$tech_id = 0;
		$orig_tech_id = 0;

		if ( $discrepancy_id > 0 ) {
			$tech_id = $discrepancy->tech_user_id;
			$orig_tech_id = $tech_id;
		}
		else if ( $from_trouble_call_id > 0 ) {
			$tech_id = $trouble_call->tech_user_id;
			$orig_tech_id = $tech_id;
		}
		else if ( strlen($tech_list->getName($user->uid)) ) {
			$tech_id = $user->uid;
		}
		$tech_name = _get_user_name($tech_id);

		if ( user_access('assign technician') ) {
			// user is allowed to assign a technician -- display dropdown list of employees from employee table

			$form['tech'] = array(
				'#type' => 'select',
				'#title' => t('Technician/Instructor'),
				'#options' => $tech_list->get_active(),
				// for new discrepancies, for user with assign privs, default to the current user in the select list if user is a tech
				// otherwise, non techs will default to '- Select -' option
				'#default_value' => $tech_id,
				'#required' => True,
				'#disabled' =>  (($discrepancy_id > 0) ? !$user_perms->edit_discrepancy : False),
				'#attributes' => array('class' => array('qms-select'),
															 'id' => 'qms-tech-select'),
			);
			$form['orig_tech'] = array(
				'#type' => 'textfield',
				'#default_value' => $orig_tech_id,
				'#attributes' => array('class' => array('qms-hidden-field')),
			);
		}
		else {
			// display the tech/user as the currently logged in user for new DRs and the user on record for saved DRs
			$form['tech_display'] = array(
				'#type' => 'item',
				'#title' => t('Technician/Instructor'),
				'#markup' => $tech_name,
			);
		}
	}



	$active_only = ( $discrepancy_id == 0) ? True : False;  // if editing, get all the customers

	if ( $user_is_customer_id ) {
  	// logged in user is a customer account, display the customer name
		// only simulators for this customer will appear in the selection list below

		$form['customer_display'] = array(
			'#type' => 'item',
			'#title' => t('Customer'),
			'#markup' => $customer_list->getName($user_is_customer_id),
		);
	}

	$sim_id = 0;
	if ( $discrepancy_id > 0 ) {
		$sim_id = $discrepancy->simulator_id;
	}
	else if ( $from_trouble_call_id > 0 ) {
		$sim_id = $trouble_call->simulator_id;
	}
	else if ( 1 == $simulator_list->get_active_count() ) {
		$sim_id = $simulator_list->get_first_active();
	}

	$form['simulator'] = array(
		'#type' => 'select',
		'#title' => t('Simulator'),
		'#options' => $simulator_list->get($active_only),
		'#default_value' => $sim_id,
		'#required' => True,
		'#disabled' =>  (($discrepancy_id > 0) ? !$user_perms->edit_discrepancy : False),
		'#attributes' => array('class' => array('qms-select'),
													 'id' => 'qms-simulator-select'),
	);


	$form['chapter'] = array(
		'#type' => 'select',
		'#title' => t('ATA Chapter'),
		'#options' => $chapter_list->get(),
		'#default_value' => (($discrepancy_id > 0) ? $discrepancy->ata_chapter_id : 0),
		'#required' => True,
		'#disabled' =>  (($discrepancy_id > 0) ? !$user_perms->edit_discrepancy : False),
		'#attributes' => array('class' => array('qms-select'),
													'id' => 'qms-chapter-select'),
		'#suffix' => '</td>',
	);


	//-----------------------------------------
	// date input doesn't display properly when disabled, switch to display_only item elements

	$form['markup_5'] = array(
		'#markup' => '<td style="width:33%">',
	);

	if ( ($discrepancy_id > 0) && ($user_perms->edit_discrepancy == False) ) {
		$form['date_opened_display'] = array(
			'#type' => 'item',
			'#title' => t('Date Opened'),
			'#markup' => _st_format_date($discrepancy->date_opened, 'short') .
                    '<span id="qms-date-opened-value" class="qms-hidden">' .
                    $discrepancy->date_opened .
                    '</span>',
			'#size' => 14,
		);
	}
	else {

		$date_opened_frmtd = '';
		if ( $discrepancy_id > 0 ) {
			$date_opened_frmtd = _st_format_date($discrepancy->date_opened, 'short');
		}
		else if ( $from_trouble_call_id > 0 ) {
			$date_opened_frmtd = _st_format_date($trouble_call->date_opened, 'short');
		}
		else {
			$date_opened_frmtd = date('Y-m-d H:i');
		}

		$form['date_opened'] = array(
			'#type' => 'date_popup',
			'#title' => t('Date Opened'),
			'#size' => 14,
			'#date_format' => 'm-d-Y H:i',						// displayed format
				//default value has to be in this format
			'#default_value' => $date_opened_frmtd,
			'#required' => True,   // if no date entered, returns NULL
			'#attributes' => array('class' => array('qms-date-picker')),
		);
	}


	if ( $user_perms->close_discrepancy == False) {
		if ( isset($discrepancy->date_closed) && ($discrepancy->date_closed > 0) ) {
			$form['date_closed'] = array(
				'#type' => 'item',
				'#title' => t('Date Closed'),
				'#markup' => ( $discrepancy->date_closed ?  _st_format_date($discrepancy->date_closed, 'short') : '' ),
				'#size' => 14,
			);
		}
	}
	else {

		$dr_closed = '';
		if ( $discrepancy_id > 0 ) {
			if ( $discrepancy->date_closed > 0 ) {
				$dr_closed = _st_format_date($discrepancy->date_closed, 'short');
			}
		}

		$form['date_closed'] = array(
			'#type' => 'date_popup',
			'#title' => t('Date Closed'),
			'#size' => 14,
			'#default_value' => $dr_closed,
			'#date_format' => 'm-d-Y H:i',
			'#required' => False,   // if no date entered, returns NULL
			//'#disabled' =>  !$user_perms->close_discrepancy,
			'#attributes' => array('class' => array('qms-date-picker')),
		);
	}

	// since date closed can appear in a number of different elements, enabled and disabled
	// we need to check its value from the browser and this is the only safe way to do it.
	// no need to format it, just store the unix time stamp value
	// only need to know if date_closed_verify > 0
	$form['date_closed_verify'] = array(
		'#type' => 'textfield',
		'#default_value' => (($discrepancy_id > 0) ? $discrepancy->date_closed : 0),
		'#attributes' => array('class' => array('qms-hidden-field'),
														'id' => 'qms-date-closed-verify'),
	);



	$form['markup_6'] = array(
		'#markup' => '</td>',
	);


	//-----------------------------------------

	$form['markup_10'] = array(
		'#markup' => '<td>',
	);


	// show dr links to eng and sd reports
	$link_count = 1;
	foreach ($dr_links as $link) {
		$form['dr_link_' . $link_count] = array(
			'#markup' => $link . '<br />',
		);
		$link_count++;
	}
	if ( $link_count > 1 ) {
    $form['markup_11'] = array(
      '#markup' => '<br />',
    );
  }


	// is user allowed to set discrepancy indicator flags : show_customer, mmi, faa, cleartime
	// if user has create discrepancy permission, they can add all of these when the DR is opened (disabled=false)
	// only enable show_customer if user has set flags permission and the show_customer is off.  Once its saved with
	// Show_customer turned ON, it can only be changed by an Admin
	$allow_show_customer_edit = ((($user_perms->set_discrepancy_flags) && ($discrepancy->show_customer == 0)) || ($user_perms->admin));
	$allow_show_customer_add = (($user_perms->set_discrepancy_flags) || ($user_perms->admin));

	// if faa, mmi, and clear_time set, don't allow it to be altered unless by an admin
	// otherwise, allow it to be set during editing
	$allow_mmi_edit = False;
	$allow_mmi_add = (($user_perms->set_discrepancy_flags) || ($user_perms->admin));
	$allow_faa_edit = False;
	$allow_faa_add = (($user_perms->set_discrepancy_flags) || ($user_perms->admin));
	$allow_clear_time_add = (($user_perms->set_discrepancy_flags) || ($user_perms->admin));
	$allow_clear_time_edit = False;

	if ( $discrepancy_id > 0 ) {
		$allow_mmi_edit = ((($user_perms->set_discrepancy_flags) && ($discrepancy->mmi == 0)) || ($user_perms->admin));
		$allow_faa_edit = ((($user_perms->set_discrepancy_flags) && ($discrepancy->faa == 0)) || ($user_perms->admin));
		$allow_clear_time_edit = ( (($discrepancy->faa || $discrepancy->mmi) && ($user_perms->admin)) ||
												       ((!$discrepancy->faa && !$discrepancy->mmi) && ($user_perms->set_discrepancy_flags)) );
	}

	if ( $discrepancy_id && $discrepancy->is_pm ) {

		$form['prev_maint'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('Preventative Maintenance'),
		);
	}

  if ( $discrepancy_id && $discrepancy->preflight ) {

		$form['preflight'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('Preflight'),
		);
	}

  if ( $discrepancy_id && $discrepancy->from_sch_assignment_id ) {
		$form['from_scheduler'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('From E-Log'),
		);
	}




	$form['show_customer'] = array(
		'#type' => 'checkbox',
		'#title' => t('Show Customer'),
		'#default_value' => (($discrepancy_id > 0) ? $discrepancy->show_customer : 0),
		'#disabled' =>  (($discrepancy_id > 0) ? !$allow_show_customer_edit : !$allow_show_customer_add ),
		'#attributes' => array('id' => 'qms-show-customer-chk'),
	);


	$form['mmi'] = array(
		'#type' => 'checkbox',
		'#title' => t('MMI'),
		'#default_value' => (($discrepancy_id > 0) ? $discrepancy->mmi : 0),
		'#disabled' => (($discrepancy_id > 0) ? !$allow_mmi_edit : !$allow_mmi_add ),
		'#attributes' => array('id' => 'qms-mmi-chk'),
	);

	$form['faa'] = array(
		'#type' => 'checkbox',
		'#title' => t('FAA'),
		'#default_value' => (($discrepancy_id > 0) ? $discrepancy->faa : 0),
		'#disabled' => (($discrepancy_id > 0) ? !$allow_faa_edit : !$allow_faa_add ),
		'#attributes' => array('id' => 'qms-faa-chk'),
	);

	$form['clear_time'] = array(
		'#type' => 'textfield',
		'#title' => t('Clear Time (in Days)'),
		'#size' => 6,
		'#maxlength' => 6,
		'#default_value' => (($discrepancy_id > 0) ? $discrepancy->clear_time : '0.00'),
		'#disabled' => (($discrepancy_id > 0) ? !$allow_clear_time_edit : !$allow_clear_time_add ),
		'#attributes' => array('id' => 'qms-clear-time-num',
														'style' => array('text-align:right')),
		'#suffix' => '</td></tr></table>',
	);

	// create a 'dirty' flag for these so we can detect changes
	$form['faa_mmi_chg'] = array(
		'#type' => 'textfield',
		'#default_value' => 0,
		'#attributes' => array('id' => 'qms-faa-mmi-chg',
													 'class' => array('qms-hidden-field')),
	);

	//------------- ADD DISCREPANCY TEXTAREA  -----------
	$dr_text = '';
	if ( $discrepancy_id > 0 ) {
		$dr_text = $discrepancy->discrepancy;
	}
	else if ( $from_trouble_call_id > 0 ) {
		$dr_text = $trouble_call->trouble_text;
	}


	$text_settings = array(
		'name' => 'discrepancy_text',
		'title' => t('Discrepancy'),
		'text' =>	$dr_text,
		'required' => True,
		'disabled' => (($discrepancy_id > 0) ? !$user_perms->edit_discrepancy : False),
	);

	_st_add_text_editor($form, $text_settings);


	//  -----------------------------------------

	// if corrective action is defined on TC, carry it through to DR, if it translates.
	// TC corr action may only apply to TCs so it may not carry over.
	$corr_action_id = 0;
	if ( $discrepancy_id > 0 ) {
		$corr_action_id = $discrepancy->corrective_action_id;
	}
	else if ( ( $from_trouble_call_id > 0 ) &&
					  ( strlen($action_list->getName(CorrectiveActionList::DR, $trouble_call->corrective_action_id)) ) ) {
		$corr_action_id = $trouble_call->corrective_action_id;
	}
	else {
		$corr_action_id = 0;
	}


	$form['corrective_action'] = array(
		'#type' => 'select',
		'#title' => t('Corrective Action (required to close)'),
		'#options' => $action_list->getList(CorrectiveActionList::DR),
		'#default_value' => $corr_action_id,
		'#required' => False,
		'#disabled' => !$user_perms->close_discrepancy,
		'#attributes' => array('id' => 'qms-corrective-action-select'),
	);

	//---------------- COMMENTS -------------------------

	$form['fs_comments'] = array(
		'#type' => 'fieldset',
		'#title' => t('Comments'),
		'#collapsible' => True,
		'#collapsed' => ( (($discrepancy_id > 0) && ($discrepancy->has_comments)) ? False : True),
	);


	$comment_table = _get_comments_table('DR', $discrepancy_id);

	$form['fs_comments']['comments'] = array(
		'#markup' => '<div id="qms-comments-div">' . $comment_table,
	);

	//------------- ADD DISCREPANCY COMMENT TEXTAREA  -----------

	// !!!! CASE SPECIFIC !!!! When a comment is entered but not added using the 'Add' comment button
	// !!!! comment will be stored and saved when the form is submitted

	unset($text_settings);  // clear previous values

	$text_settings = array(
		'name' => 'comment_text',
		'title' => t('Add Comment'),
		'text' =>	'',
		'required' => False,
		'disabled' => (($discrepancy_id > 0) ? !$user_perms->add_discrepancy_comments : False),
		'omit_length' => True,
		'fieldset' => 'fs_comments',
		'prefix' => '<table class="qms-plain-table" style="width:100%"><tr><td>',
		'suffix' => '</td></tr></table>',
	);

	_st_add_text_editor($form, $text_settings);

	//  -----------------------------------------

	// can this user add new comments to a DR during an edit?
	// if user has create DR permission, then this should always be allowed
	// add and edit shares the same button need to enable if either perm is allowed, but if you can edit, you should be able to add
	// if you can't edit, then you won't see the "edit" link from the admin column
	$allow_add_comments_dr_edit = ($user_perms->add_discrepancy_comments || $user_perms->edit_discrepancy_comments || $user_perms->admin);
  //$allow_add_comments_dr_edit  = true;

	$form['fs_comments']['add_comment'] = array(
		'#type' => 'button',
		'#value' => t('Add'),
		'#attributes' => array('id' => 'qms-btn-add-comment',
                           'class' => array('qms-btn-reports'),
													 'qms-url' => (( $discrepancy_id > 0 ) ?
																url('discrepancy/comment/update') :
																url('theme_comments_table'))),
		'#disabled' => ( ($discrepancy_id > 0) ? !$allow_add_comments_dr_edit : False),
		'#prefix' => '<div class="qms-actions">',
	);
  $form['fs_comments']['clear_comment'] = array(
		'#type' => 'button',
		'#value' => t('Clear'),
		'#attributes' => array('id' => 'qms-btn-clear-comment',
                           'class' => array('qms-btn-extra', 'qms-btn-reports')),
		'#disabled' => ( ($discrepancy_id > 0) ? !$allow_add_comments_dr_edit : False),
		//'#prefix' => '<div class="qms-actions">',
		'#suffix' => '<span id="qms-waiting-comments" class="qms-waiting"><img class="qms-waiting-img" src="' . $base_url . QMS_IMAGES_DIR . 'waiting.gif" /></span></div>',

	);

	if ( $discrepancy_id == 0 ) {  // storage field for new discrepancies, adding comments
		// need to wrap this in a hidden div since the textarea seems to want to display the grabber bar
		$form['fs_comments']['comments_to_add'] = array(
			'#type' => 'textarea',
			'#default_value' => '',
			'#prefix' => '<div id="qms-comments-hidden" class="qms-hidden-field">',
			'#attributes' => array('id' => 'qms-comments-to-add'),
			'#suffix' => '</div>',
		);
	}
	else {
		// during edits, stores the comment id in a hidden value
		$form['fs_comments']['comment_id'] = array(
			'#type' => 'textfield',
			'#default_value' => '',
			'#attributes' => array('id' => 'qms-comment-id',
															'class' => array('qms-hidden-field')),
		);
	}

	$form['fs_comments']['comments_end_div'] = array(
		'#markup' => '</div>',
	);


	//-------------------- PARTS ---------------------

	$form['fs_parts'] = array(
		'#type' => 'fieldset',
		'#title' => t('Parts Used'),
		'#collapsible' => True,
		'#collapsed' => ((($discrepancy_id > 0) && ($discrepancy->parts_used)) ? False : True),
	);


	$parts_table = _get_discrepancy_parts_table($discrepancy_id, $user_perms->edit_discrepancy_parts);

	$form['fs_parts']['parts'] = array(
		'#markup' => '<div id="qms-parts-div">' . $parts_table,
	);

	$form['fs_parts']['part_no'] = array(
		'#type' => 'textfield',
		'#size' => 10,
		'#maxlength' => 100,
		'#title' => t('Add:  Part No.'),
		'#attributes' => array('id' => 'qms-part-no'),
		'#prefix' => '<table class="qms-plain-table"><tr><td>',
		'#suffix' => '</td>',
	);

	$form['fs_parts']['part_qty'] = array(
		'#type' => 'textfield',
		'#size' => 3,
		'#maxlength' => 5,
		'#title' => t('Quantity'),
		'#attributes' => array('id' => 'qms-part-qty',
													'class' => array('qms-numeric')),
		'#prefix' => '<td>',
		'#suffix' => '</td>',
	);

	$form['fs_parts']['part_description'] = array(
		'#type' => 'textfield',
		'#size' => 42,
		'#maxlength' => 255,
		'#title' => t('Description'),
		'#attributes' => array('id' => 'qms-part-desc'),
		'#prefix' => '<td>',
		'#suffix' => '</td>',
	);
  $form['fs_parts']['serial_number_in'] = array(
		'#type' => 'textfield',
		'#size' => 12,
		'#maxlength' => 50,
		'#title' => t('S/N In'),
		'#attributes' => array('id' => 'qms-part-sn-in'),
		'#prefix' => '<td>',
		'#suffix' => '</td>',
	);
  $form['fs_parts']['serial_number_out'] = array(
		'#type' => 'textfield',
		'#size' => 12,
		'#maxlength' => 50,
		'#title' => t('S/N Out'),
		'#attributes' => array('id' => 'qms-part-sn-out'),
		'#prefix' => '<td>',
		'#suffix' => '</td></tr></table>',
	);

	// can this user add new comments to a DR during an edit?
	// if user has create DR permission, then this should always be allowed
	// add and edit shares the same button need to enable if either perm is allowed, but if you can edit, you should be able to add
	// if you can't edit, then you won't see the "edit" link from the admin column
	$allow_add_parts_dr_edit = ($user_perms->add_discrepancy_parts || $user_perms->edit_discrepancy_parts || $user_perms->admin);


	$form['fs_parts']['add_parts'] = array(
		'#type' => 'button',
		'#value' => t('Add'),
		'#attributes' => array('id' => 'qms-btn-add-part',
                            'class' => array('qms-btn-reports'),
																	 'qms-url' => (( $discrepancy_id > 0 ) ?
																				url('discrepancy/part/update') :
																				url('discrepancy/theme_add_parts_table'))),
		'#disabled' => ( ($discrepancy_id > 0) ? !$allow_add_parts_dr_edit : False),
		'#prefix' => '<div class="qms-actions">',
	);
  $form['fs_parts']['clear_part'] = array(
		'#type' => 'button',
		'#value' => t('Clear'),
		'#attributes' => array('id' => 'qms-discrepancy-btn-clear-part',
                           'class' => array('qms-btn-extra', 'qms-btn-reports')),
		'#disabled' => ( ($discrepancy_id > 0) ? !$allow_add_comments_dr_edit : False),
		//'#prefix' => '<div class="qms-actions">',
		'#suffix' =>
      '<span id="qms-waiting-parts" class="qms-waiting"><img class="qms-waiting-img" src="' .
      $base_url . QMS_IMAGES_DIR . 'waiting.gif" /></span></div>',

	);

	if ( $discrepancy_id == 0 ) {
		// storage field for new discrepancies when adding parts
		// since nothing saved to database until discrepancy is submitted
		// need to wrap this in a hidden div since the textarea seems to want to display the grabber bar
		$form['fs_parts']['parts_to_add'] = array(
			'#type' => 'textarea',
			'#default_value' => '',
			'#prefix' => '<div id="qms-parts-hidden" class="qms-hidden-field">',
			'#attributes' => array('id' => 'qms-parts-to-add'),
			'#suffix' => '</div>',
		);
	}
	else {
		// during edits, stores the part id in a hidden value
		$form['fs_parts']['part_id'] = array(
			'#type' => 'textfield',
			'#default_value' => '',
			'#attributes' => array('id' => 'qms-part-id',
															'class' => array('qms-hidden-field')),
		);
	}

	$form['fs_parts']['parts_end_div'] = array(
		'#markup' => '</div>',
	);



	//------------------ FILES -----------------------

	$collapse = True;
	if ( $discrepancy_id && $discrepancy->files_attached) {
		$collapse = False;
	}

	$form['fs_files'] = array(
		'#type' => 'fieldset',
		'#title' => t('File Attachments'),
		'#collapsible' => True,
		'#collapsed' => $collapse,
	);

	$form['fs_files']['files_begin_div'] = array(
		'#markup' => '<div id="qms-files-div">',
	);


	$files_table = array();

	// Get a table of existing uploaded files for this DR
	if ($discrepancy_id > 0) {

		$files_table = _get_discrepancy_files_table($discrepancy_id);

		if ( $discrepancy_id > 0 ) {
			$form['fs_files']['files'] = array(
				'#markup' => $files_table,
			);
		}
	}

	$allow_add_files = ($user_perms->add_discrepancy_files || $user_perms->admin);

	if ( !$discrepancy_id || $allow_add_files ) {
		$form['fs_files']['chk_add_file'] = array(
			'#type' => 'checkbox',
			'#title' => t('Add Files to this Report') .
					'<span id="qms-waiting-files" class="qms-waiting"><img class="qms-waiting-img" src="' .
							$base_url . QMS_IMAGES_DIR . 'waiting.gif" /></span>',
			'#default_value' => 0,
			'#attributes' => array('id' => 'qms-add-files-chk'),
			//'#prefix' => '<div id="qms-add-files-chk-div">',  // this div is for space & positioning w/css & anim. waiting gif
			'#suffix' => '<div class="qms-desc">You will be prompted to upload files on the next screen.</div>',
			);

	}


	$form['fs_files']['files_end_div'] = array(
		'#markup' => '</div>',
	);


  //------------------ Form Actions (Buttons) ---------------------

	$form['actions'] = array('#type' => 'actions');
	$form['actions']['submit'] = array(
		'#type' => 'submit',
		'#value' => 'Submit',
    '#name' => 'submit',  // name used to id button in submit
		'#attributes' => array('class' => array('qms-btn-submit')),
	);

  if ( $discrepancy_id && $user_perms->admin ) {
		// if the user is an Admin, allow for delete

    $form['actions']['delete'] = array(
      '#type' => 'submit',
      '#value' => t('Delete'),
      '#name' => 'delete', // name used to id button in submit
      '#attributes' => array('class' => array('qms-btn-delete', 'qms-btn-extra')),
      // not working correctly as form values never get processed.  we need this
      //'#limit_validation_errors' => array(), // do not validate form
      //'#submit' => array('discrepancy_form_button_delete'),
    );
  }

  $form['actions']['done'] = array(
		'#type' => 'button',
		'#value' => t('Done'),
    '#name' => 'done',
		'#attributes' => array('class' => array('qms-btn-done', 'qms-btn-extra'),
                           'onclick' => 'window.location="' . url($goto_url) .
                                        '"; return false;'),
	);


  //------------------ Hidden ---------------------
	// storage area for dynamic dialog elements
	$form['popup_dialog'] = array(
		'#type' => 'markup',
		'#markup' => '<div id="qms-message-box"></div>',
	);


	$form['report_changed'] = array(
		'#type' => 'textfield',
		'#default_value' => 0,
		'#attributes' => array('id' => 'qms-report-changed',
														'class' => array('qms-hidden-field')),
	);


	if ( $discrepancy_id > 0 ) {
		$form['date_closed_dirty'] = array(
			'#type' => 'textfield',
			'#default_value' => 0,
			'#size' => 5,
			'#attributes' => array('id' => 'qms-date-closed-changed',
															'class' => array('qms-hidden-field')),
		);
	}

	return $form;
}

/*------ AFTER BUILD FUNCTION --------
*	 functions called, as it implies, after the form is built
*  this is necessary when custom javascript and/or css files are added as needed
*  at the page level for forms that go through validation with hook_form_validate()
*  Otherwise, if a form fails validation, the page/form is reloaded for the user to correct
*  but the accompanying javascript & css is not reloaded with it.
*  when $form['#after_build][] is used, the external scripts will be reloaded properly.
*/

/*
 * discrepancy_form_after_build()
 *
 */
function discrepancy_form_after_build($form, &$form_state)
{
	drupal_add_library('system','ui.datepicker');
	drupal_add_library('system','ui.dialog');

  _st_add_js_timezone();

  $sabreTools = drupal_get_path('module', 'sabreTools');
	drupal_add_js( $sabreTools . '/js/sabreTools.lib.js');
	drupal_add_js($sabreTools . '/js/sabreTools.ckeditor.js');



	if ( (int)$form['discrepancy_id']['#default_value'] == 0) {
		drupal_add_js(drupal_get_path('module', 'sabreQMS') . '/js/sabreQMS.discrepancyadd.js');
	}
	else {
		drupal_add_js(drupal_get_path('module', 'sabreQMS') . '/js/sabreQMS.discrepancyedit.js');
	}

	// WYSIWYG EDITOR??  Is this feature enabled allowing for the editor
	if ( isset( $form['ckeditor_module_path'])  ) {
		global $base_url;
		drupal_add_js( $base_url . QMS_CKEDITOR_PATH_CONFIG);
		// need to specify preprocess == false otherwise 'Aggregate Javascript' setting in drupal
		// causes ckeditor not to load properly
		// adding scope to footer speeds up the page load
		drupal_add_js( $base_url . QMS_CKEDITOR_LIB, array('type' => 'file', 'scope' => 'footer', 'preprocess' => FALSE));
	}

	return $form;
}



/*
 *	discrepancy_form_validate()
 *
 *  Overloads hook_form_validate()
 *  Validation for the discrepancy_form
 */

function discrepancy_form_validate($form, $form_state) {

  // 'Submit not clicked, bypass validation
  // DRUPAL BUG: #limit_validation_errors to bypass this, but not working
  if($form['actions']['submit']['#name'] != $form_state['triggering_element']['#name']){
    return $form;
  }

	$err_msg = 'Required fields missing.  ';


	if ( (int) $form_state['values']['simulator'] == 0 ) {
		form_set_error('simulator', t($err_msg . 'Simulator is a required field'));
	}


	if ( (int) $form_state['values']['chapter'] == 0 ) {
		form_set_error('chapter', t($err_msg . 'ATA Chapter is a required field'));
	}
	if ( ( ((int)$form_state['values']['faa'] == 1) ||
	 		   ((int)$form_state['values']['mmi'] == 1))   &&
			 ( (float)$form_state['values']['clear_time'] == 0 )) {
		form_set_error('clear_time', t($err_msg . 'When FAA or MMI is marked, Clear Time is a required field'));
	}

	$dr_text = trim($form_state['values']['discrepancy_text_editor_value']);
	if ( $dr_text == '' ) {
		form_set_error('qms_discrepancy_text', t($err_msg . 'Discrepancy is a required field'));
	}


	//----------------- date checking ---------------------

	// add seconds to make it DATE_ISO format:  'YYYY-MM-DD HH24:MI:SS'
	// date_opened may not always be present if the element is display only due to permission restrictions
	$date_opened = '';
	$idate_opened = 0;
	if ( isset($form_state['values']['date_opened']) ) {
		$date_opened = $form_state['values']['date_opened'];
		$idate_opened = _st_format_timestamp($date_opened);
		if ( $idate_opened == 0 ) {
			form_set_error('date_opened', t($err_msg . 'Date Opened is a required field'));
		}
	}


	$date_closed = ( isset($form_state['values']['date_closed']) ? $form_state['values']['date_closed'] : '' );
	$idate_closed = 0;
	if ( $date_closed <> '' ) {
		$idate_closed = _st_format_timestamp($date_closed);
	}

	if ( $idate_closed > 0 )  {
		if ( (int)$form_state['values']['corrective_action'] == 0 ) {
			form_set_error('corrective_action', t($err_msg . 'When Discrepancy is being closed, a Corrective Action is required.'));
		}

		// this is ok since you have to have edit permissions in order to be able to close a DR
		if ( ($idate_opened > 0) && ($idate_closed > 0) && ($idate_closed < $idate_opened)) {
			form_set_error('date_closed', t('Date Closed cannot be set to a date earlier than the Date Opened.'));
		}
	}
}

/*
 *	discrepancy_form_submit()
 *
 *  Overloads hook_form_submit()
 *  Final submit action for the discrepancy_form
 *  Stores input data to the db
 */

function discrepancy_form_submit($form, $form_state) {


  $button_clicked = $form_state['triggering_element']['#name'];

  if( $form['actions']['submit']['#name'] == $button_clicked ){
      //Process if Submit is pressed
    if ( 0 == (int)$form_state['values']['discrepancy_id'] )  {
      // this is a new discrepancy being added
      _create_discrepancy_report($form, $form_state);
    }
    else {
      _update_discrepancy_report($form, $form_state);
    }
  }
  else if ( isset($form['actions']['delete']['#name']) &&
            ($form['actions']['delete']['#name'] == $button_clicked ))  {
      //Process if Delete is pressed
    $discrepancy_id = isset($form_state['values']['discrepancy_id']) ?
                        (int)$form_state['values']['discrepancy_id'] : 0;

    if ( !$discrepancy_id && isset($form['discrepancy_id']['#default_value'])) {
      $discrepancy_id = (int) $form['discrepancy_id']['#default_value'];
    }

    if ( $discrepancy_id ) {
      $_GET['destination'] = 'discrepancy/delete/' . $discrepancy_id .
                            '?destination=discrepancy/edit/' . $discrepancy_id;
    }
  }
  else if ( isset($form['actions']['done']['#name']) &&
           ( $form['actions']['done']['#name'] == $button_clicked )) {
      //Process if Done is pressed
    $destination = drupal_get_destination();
    $goto_url = $destination['destination'];

    if( !strlen($goto_url) || ($goto_url == current_path()) ) {
      $goto_url = 'search/discrepancy';
    }
    drupal_goto($goto_url);
  }

}

/*
 *	discrepancy_form_button_delete()
 *
 *  Button Handler for Delete button
 */
/*
function discrepancy_form_button_delete($form, $form_state) {

 	$discrepancy_id = isset($form_state['values']['discrepancy_id']) ?
                        (int)$form_state['values']['discrepancy_id'] : 0;

  if ( !$discrepancy_id && isset($form['discrepancy_id']['#default_value'])) {
    $discrepancy_id = (int) $form['discrepancy_id']['#default_value'];
  }

  if ( $discrepancy_id ) {
    $_GET['destination'] = 'discrepancy/delete/' . $discrepancy_id .
                          '?destination=discrepancy/edit/' . $discrepancy_id;
  }
}*/

/*
 *	discrepancy_form_button_done()
 *
 *  Button Handler for Cancel/Done button
 */
/*
function discrepancy_form_button_done($form, $form_state) {

	$destination = drupal_get_destination();
	$goto_url = $destination['destination'];

	if( !strlen($goto_url) || ($goto_url == current_path()) ) {
		$goto_url = 'search/discrepancy';
	}
	drupal_goto($goto_url);
}*/




/*------ VIEW --------*/

/*
 *	view_discrepancy_form()
 *
 *  Overloads hook_form()
 *  Discrepancy VIEW ONLY form
 */

function view_discrepancy_form($form, $form_state, $discrepancy_id = 0) {

	if ( user_access('search view reports') == FALSE ) {
    drupal_set_message( t('Unauthorized:  Permission is required'), 'status');
		return;
  }

	if ( $discrepancy_id == 0 ) {
		return;
	}

	drupal_add_js(drupal_get_path('module', 'sabreQMS') . '/js/sabreQMS.view.js');

	$discrepancy = (object) Null;
	$dr_comments = array();
	$dr_parts = array();
	$dr_files = array();

	// get the discrepancy record
	$discrepancy = _get_discrepancy($discrepancy_id);

	if ( $discrepancy == (object) Null ) {
		drupal_set_message( t('Discrepancy Not Found!'), 'warning');
		drupal_goto('search/discrepancy');
		return;
	}

	$dr_links = _get_discrepancy_linked_reports($discrepancy, 'discrepancy/view/' . $discrepancy_id);


	//------------ BUILD VIEW-ONLY FORM ------------------

	$form['dr_no'] = array(
		'#type' =>'item',
		'#markup' => '<div class="qms-report-no">' . t($discrepancy->dr_no) . '</div>',
		'#suffix' => _st_format_record_timestamp_table($discrepancy),
	);

  $form['discrepancy_id'] = array(
		'#type' =>'textfield',
		'#default_value' => $discrepancy_id,
		'#attributes' => array('class' => array('qms-hidden')),
	);

	//-----------------------------------------

	//global $customer_list;
	global $chapter_list;
	global $tech_list;
	global $simulator_list;
	global $action_list;


	$form['tech'] = array(
		'#type' => 'item',
		'#title' => t('Technician/Instructor'),
		'#markup' => (($discrepancy->tech_user_id) ? _get_user_name($discrepancy->tech_user_id) : '[unassigned]'),
		'#prefix' => '<table class="qms-plain-table" style="width:100%"><tr><td style="width:40%">',
	);

	$form['customer'] = array(
		'#type' => 'item',
		'#title' => t('Customer'),
		'#markup' => _get_simulator_customer_name($discrepancy->simulator_id),

	);

	$form['simulator'] = array(
		'#type' => 'item',
		'#title' => t('Simulator'),
		'#markup' => $simulator_list->getName($discrepancy->simulator_id),

	);

	$form['chapter'] = array(
		'#type' => 'item',
		'#title' => t('ATA Chapter'),
		'#markup' => $chapter_list->getName($discrepancy->ata_chapter_id),
		'#suffix' => '</td>',
	);


	//-----------------------------------------
	$form['date_opened'] = array(
		'#type' => 'item',
		'#title' => t('Date Opened'),
		'#markup' => _st_format_date($discrepancy->date_opened, 'short'),
		'#size' => 14,
		'#prefix' => '<td style="width:33%">',
	);

	if ( $discrepancy->date_closed ) {
		$form['date_closed'] = array(
			'#type' => 'item',
			'#title' => t('Date Closed'),
			'#markup' => ( $discrepancy->date_closed ?  _st_format_date($discrepancy->date_closed, 'short') : '' ),
			'#size' => 14,
			'#suffix' => '</td>',
		);
	}
	$form['markup_dates'] = array(
		'#markup' => '</td>',
	);



	//-----------------------------------------

	$form['markup1'] = array(
		'#markup' => '<td>',
	);

	global $base_url;  // need the base url for accessing the  sites/default/files directory

	$link_count = 1;
	foreach ($dr_links as $link) {
		$form['dr_link_' . $link_count] = array(
			'#markup' => $link . '<br />',
		);
		$link_count++;
	}

	$form['markup2'] = array(
		'#markup' => '<br />',
	);


	if ( $discrepancy->show_customer ) {
		$form['show_customer'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('Show Customer'),
		);
	}
  if ( $discrepancy->from_sch_assignment_id ) {
		$form['from_scheduler'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('From E-Log'),
		);
	}

	if ( $discrepancy->is_pm ) {
		$form['prev_maint'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('Preventative Maintenance'),
		);
	}

  if ( $discrepancy->preflight ) {
		$form['preflight'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('Preflight'),
		);
	}



	$form['markup3'] = array(
		'#markup' => '<br />',
	);

	if ( $discrepancy->mmi ) {
		$form['mmi'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('MMI'),
		);
	}

	if ( $discrepancy->faa ) {
		$form['faa'] = array(
			'#type' => 'item',
			'#title' => '<span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' . t('FAA'),
		);
	}

	if ( $discrepancy->mmi || $discrepancy->faa ) {
		$form['clear_time'] = array(
			'#type' => 'item',
			'#title' => t('Clear Time (in Days)'),
			'#markup' =>  $discrepancy->clear_time,
		);
	}

	$form['markup4'] = array(
		'#markup' => '</td></tr></table>',
	);



	//-----------------------------------------

	// these items placed in a table for style consistency with the rest of the elements

	// WYSIWYG EDITOR??  If enabled, we format differently for textareas than for the editor
	$ckeditor_activated = variable_get(QMS_VAR_WYSIWYG_EDITOR, 1);  // if not set, default to ON


	$form['discrepancy_text'] = array(
		'#type' => 'item',
		'#title' => t('Discrepancy'),
		'#prefix' => '<table class="qms-plain-table" style="width:100%"><tr><td>',
		'#markup' =>  ($ckeditor_activated ? _st_convert_symbols($discrepancy->discrepancy) : nl2br(_st_convert_symbols($discrepancy->discrepancy))),
		'#suffix' => '</td></tr>',
	);


	$form['corrective_action'] = array(
		'#type' => 'item',
		'#title' => t('Corrective Action'),
		'#markup' => ( $discrepancy->corrective_action_id ?
				$action_list->getName(CorrectiveActionList::DR, $discrepancy->corrective_action_id) :
				'[' . t('None') . ']'),
		'#prefix' => '<tr><td>',
		'#suffix' => '</td></tr>',
	);

	$form['markup_discrep'] = array(
		'#markup' => '</table>',
	);


	//---------------- COMMENTS -------------------------

	$table_headers = array();
	$table_rows = array();

	if ( $discrepancy->has_comments ) {
		$comment_table = _get_comments_table('DR', $discrepancy_id, True);  //edit=false, view_only=true

		$form['comments'] = array(
			'#markup' => $comment_table,
						//'#prefix' => '<div id="qms-comments-div">',
						//'#suffix' => '</div>',
		);

	}


	//-------------------- PARTS ---------------------

	if ( $discrepancy->parts_used ) {
		$parts_table = _get_discrepancy_parts_table($discrepancy_id, False, True); // edit=false, view_only=true

		$form['parts'] = array(
			'#markup' => $parts_table,
						//'#prefix' => '<div id="qms-parts-tbl-div">',
						//'#suffix' => '</div>',
		);

	}

	//------------------ FILES -----------------------

	if ( $discrepancy->files_attached ) {

		$files_table = _get_discrepancy_files_table($discrepancy_id, True);  //view_only=true

		$form['files'] = array(
			'#markup' => $files_table,
					//'#prefix' => '<div id="qms-files-tbl-div">',
					//'#suffix' => '</div>',
		);
	}

	$next_report_link = '';
	$prev_report_link = '';

	$destination = drupal_get_destination();
	$goto_url = $destination['destination'];

	if( !strlen($goto_url) || ($goto_url == current_path()) ) {
		$goto_url = 'search/discrepancy';
	}

	// determine the next or previous in the search results list of the current page
	$results_cache_name = _get_qms_cache_name(QMS_DISCREPANCY_SEARCH_RESULTS);
	$results_cache = cache_get($results_cache_name);

	if ( isset($results_cache->data) && ($results_cache->data <> '') ) {
		$dr_search_results = $results_cache->data;
		$dr_results_table_rows = $dr_search_results->getResults();
		$prev_id = _st_array_key_relative($dr_results_table_rows, $discrepancy_id, -1);
		if ( $prev_id !== False ) {
      /*
			$prev_report_link = l(t('View Previous'), 'discrepancy/view/' . $prev_id,
			 													array('query' => array('destination' => 'search/discrepancy')));*/
      $form['view_previous_link'] = array(
        '#type' => 'textfield',
        '#default_value' => 'discrepancy/view/' . $prev_id,
        '#attributes' => array('class' => array('qms-hidden') ),
      );
		}
		$next_id = _st_array_key_relative($dr_results_table_rows, $discrepancy_id, 1);
		if ( $next_id !== False ) {
      /*
			$next_report_link = l(t('View Next'), 'discrepancy/view/' . $next_id,
																array('query' => array('destination' => 'search/discrepancy'))); */
      $form['view_next_link'] = array(
        '#type' => 'textfield',
        '#default_value' => 'discrepancy/view/' . $next_id,
        '#attributes' => array('class' => array('qms-hidden')),
      );
		}

	}


	$form['actions'] = array( '#type' => 'actions');
	$form['actions']['submit'] = array(
		'#type' => 'submit',
		'#value' => t('Done'),
    '#name' => 'submit',  // the main action is always submit even if the label isnt
		'#attributes' => array('class' => array('qms-btn-submit')),
	);

  $form['actions']['print'] = array(
		'#type' => 'button',
		'#value' => t('Print'),
    '#name' => 'print',
		'#attributes' => array('class' => array('qms-print', 'qms-btn-extra')),
	);



	if ( (0 == $discrepancy->date_closed) || ( True == user_access('administer sabreQMS') ) ) {
    $form['actions']['edit'] = array(
      '#type' => 'submit',
      '#value' => t('Edit'),
      '#name' => 'edit',
      '#attributes' => array('class' => array('qms-btn-edit', 'qms-btn-extra'),
                              'query' => array('destination' => 'discrepancy/view/' . $discrepancy_id)),
      //'#limit_validation_errors' => array(),
      //'#validate' => array(),
      //'#submit' => array('view_discrepancy_form_button_edit'),
    );
  }


 //		$form['actions']['edit'] = array(
 //			'#markup' => l(t('Edit') , 'discrepancy/edit/' . $discrepancy_id,
 //			 										array('query' => array('destination' => 'discrepancy/view/' . $discrepancy_id))),
 //		);



	if ( isset($form['view_previous_link']) ) {
		$form['actions']['view_previous'] = array(
			'#type' => 'submit',
      '#value' => t('View Previous'),
      '#name' => 'view_previous',
      '#attributes' => array('class' => array('qms-btn-previous', 'qms-btn-extra'),
                              'query' => array('destination' => 'discrepancy/view/' . $discrepancy_id)),
      //'#limit_validation_errors' => array(),
      //'#validate' => array(),
      //'#submit' => array('view_discrepancy_form_button_previous'),
		);
	}

	if ( isset($form['view_next_link']) ) {
		$form['actions']['view_next'] = array(
			'#type' => 'submit',
      '#value' => t('View Next'),
      '#name' => 'view_next',
      '#attributes' => array('class' => array('qms-btn-next', 'qms-btn-extra'),
                              'query' => array('destination' => 'discrepancy/view/' . $discrepancy_id)),
      //'#limit_validation_errors' => array(),
      //'#validate' => array(),
      //'#submit' => array('view_discrepancy_form_button_next'),
		);
	}


	return $form;
}


/*
 *	view_discrepancy_form_submit()
 *
 *  Overloads hook_form_submit()
 *  Discrepancy VIEW ONLY submit handler, just routes
 */


function view_discrepancy_form_submit($form, $form_state) {

  $button_clicked = $form_state['triggering_element']['#name'];

  if($form['actions']['submit']['#name'] == $button_clicked ){
    $destination = drupal_get_destination();
    $goto_url = $destination['destination'];

    if( !strlen($goto_url) || ($goto_url == current_path()) ) {
      $goto_url = 'search/discrepancy';
    }
    drupal_goto($goto_url);
  }
  else if ( isset($form['actions']['edit']['#name']) &&
            ($form['actions']['edit']['#name'] == $button_clicked)) {

    $discrepancy_id = isset($form_state['values']['discrepancy_id']) ?
                        (int) $form_state['values']['discrepancy_id'] : 0;


    if ( !$discrepancy_id && isset($form['discrepancy_id']['#default_value'])) {
      $discrepancy_id = (int) $form['discrepancy_id']['#default_value'];
    }

    if ( $discrepancy_id ) {

      // we have to force $_GET['destination'] otherwise drupal_goto
      // ignores the supplied path and reverts to the destination setting
      $_GET['destination'] = 'discrepancy/edit/' . $discrepancy_id .
                '?destination=discrepancy/view/' . $discrepancy_id;
    }
  }
  else if ( isset($form['actions']['view_previous']['#name']) &&
            ($form['actions']['view_previous']['#name'] == $button_clicked)) {

    $prev_link = isset($form_state['values']['view_previous_link']) ?
                  $form_state['values']['view_previous_link'] : '';
    if ( !strlen($prev_link) ) {
      $prev_link = isset($form['view_previous_link']) ?
                    $form['view_previous_link']['#default_value'] : '';
    }
    if ( strlen($prev_link) ) {
      $_GET['destination'] = $prev_link . '?destination=search/discrepancy';
    }
  }
  else if ( isset($form['actions']['view_next']['#name']) &&
            ($form['actions']['view_next']['#name'] == $button_clicked)) {

    $next_link = isset($form_state['values']['view_next_link']) ?
                  $form_state['values']['view_next_link'] : '';
    if ( !strlen($next_link) ) {
      $next_link = isset($form['view_next_link']) ?
                    $form['view_next_link']['#default_value'] : '';
    }
    if ( strlen($next_link) ) {
      $_GET['destination'] = $next_link . '?destination=search/discrepancy';
    }
  }



}





/*
 *	discrepancy_preflight_form()
 *
 *  overloads:  hook_form()
 *
 *	Create Discrepancy (only)
 *  Displays a Discrepancy Entry form specifically for Daily Preflight entries (manual)
 *  Majority of Daily Preflight DRs can be generated automatically from Preventative Maintenance feature
 */


function discrepancy_preflight_form($form, $form_state) {


	global $base_url;

	$user_perms = (object) Null;
	$user_perms->admin = user_access('administer sabreQMS');

	$user_perms->create_discrepancy = False;
	//$user_perms->set_discrepancy_flags = False;
  $user_perms->create_discrepancy = user_access('create discrepancy');

  if ( ( $user_perms->create_discrepancy == FALSE) && ($user_perms->admin == FALSE) ) {
    drupal_set_message( t('Unauthorized:  Permission required'), 'status');
    return $form;
  }


	$discrepancy = (object) Null;
	$dr_links = array();
	$dr_no_base = '';

  //------------------ AFTER BUILD ------------------------
	// use the same after build function as the regular discrepancy_form
	$form['#after_build'][] = 'discrepancy_form_after_build';


	//------------------- ROUTING ---------------------------
	// determine the return routing url

	$destination = drupal_get_destination();
	$goto_url = $destination['destination'];

	if( !strlen($goto_url) || ($goto_url == current_path()) ) {
		$goto_url = 'search/discrepancy';
	}


  //------------------- DR Base No ------------------------

  //  Determine the new DR No when submitted
  $dr_no_base = _st_generate_report_base_no('DR');



	//-------------------- BUILD FORM --------------------------

	// storage field for the discrepancy_id (edit) -- hidden
  // even though this will always be zero for preflight, we need it to exist
	$form['discrepancy_id'] = array(
		'#type' => 'textfield',
		'#default_value' => 0,   // this behaves as a flag for the _create_discrepancy() function
		'#attributes' => array('id' => 'qms-discrepancy-id',
													 'class' => array('qms-hidden-field')),
	);


  $form['dr_no_display'] = array(
    '#title' => t('DR No.'),
    '#type' =>'item',
    '#markup' => '<div class="qms-report-no">' . $dr_no_base . '___</div>',
    '#suffix' => '<div class="qms-desc">Assigned when submitted.</div><hr />',
  );



	$form['dr_no'] = array(
		'#type' =>'textfield',
		'#default_value' => $dr_no_base,
		'#attributes' => array('class' => array('qms-hidden-field')),
	);


	//-----------------------------------------

	global $customer_list;
	global $chapter_list;
	global $tech_list;
	global $simulator_list;  // if user is linked to a customer, this list will only be sims for that customer
	//global $action_list;

	global $user;
  global $base_url;



	// setup a plain table for form layout
	$form['markup_1'] = array(
		'#markup' =>
     '<table class="qms-plain-table" style="width:100%"><tr><td style="width:70%">',
	);

	// USER IS CUSTOMER?
	$user_is_customer_id = _user_is_customer($user->uid);


	if ( $user_is_customer_id ) {
		// user is not allowed to (re)assign a technician, display only element
		// display the tech/user	as the currently logged in user for new DRs and the user on record for saved DRs

		$form['tech'] = array(
			'#type' => 'item',
			'#title' => t('Technician/Instructor'),
			'#markup' => t('[unassigned]'),
		);
	}
	else {
		$tech_id = 0;
		$orig_tech_id = 0;

		if ( strlen($tech_list->getName($user->uid)) ) {
			$tech_id = $user->uid;
		}
		$tech_name = _get_user_name($tech_id);

		if ( user_access('assign technician') ) {
			// user is allowed to assign a technician -- display dropdown list of employees from employee table

			$form['tech'] = array(
				'#type' => 'select',
				'#title' => t('Technician/Instructor'),
				'#options' => $tech_list->get_active(),
				// for new discrepancies, for user with assign privs, default to the current user in the select list if user is a tech
				// otherwise, non techs will default to '- Select -' option
				'#default_value' => $tech_id,
				'#required' => True,
				'#disabled' =>  False,
				'#attributes' => array('class' => array('qms-select'),
															 'id' => 'qms-tech-select'),
			);

		}
		else {
			// display the tech/user as the currently logged in user for new DRs
      // and the user on record for saved DRs
			$form['tech_display'] = array(
				'#type' => 'item',
				'#title' => t('Technician/Instructor'),
				'#markup' => $tech_name,
			);
		}
	}





	if ( $user_is_customer_id ) {
  	// logged in user is a customer account, display the customer name
		// only simulators for this customer will appear in the selection list below

		$form['customer_display'] = array(
			'#type' => 'item',
			'#title' => t('Customer'),
			'#markup' => $customer_list->getName($user_is_customer_id),
		);
	}

	$sim_id = 0;
	if ( 1 == $simulator_list->get_active_count() ) {
		$sim_id = $simulator_list->get_first_active();
	}

	$form['simulator'] = array(
		'#type' => 'select',
		'#title' => t('Simulator'),
		'#options' => $simulator_list->get($active_only = True),
		'#default_value' => $sim_id,
		'#required' => True,
		'#disabled' => False,
		'#attributes' => array('class' => array('qms-select'),
													 'id' => 'qms-simulator-select'),
	);

	/*
	$form['chapter'] = array(
		'#type' => 'select',
		'#title' => t('ATA Chapter'),
		'#options' => $chapter_list->get(),
		'#default_value' => 0,
		'#required' => True,
		'#disabled' =>  False,
		'#attributes' => array('class' => array('qms-select'),
													'id' => 'qms-chapter-select'),
	);
   * */




	//-----------------------------------------
	// date input doesn't display properly when disabled, switch to display_only item elements


  //-----------------------------------------
	$form['markup_5'] = array(
		'#markup' => '</td><td>',
	);


  // PREFLIGHT INDICATOR IS SET, ICON DISPLAYS
  $form['preflight_icon'] = array(
    '#markup' => '<br /><span><img src="' . $base_url . QMS_IMAGES_DIR . 'checkmark.gif' . '" /></span>&nbsp;' .
                  t('Preflight'),
  );
  $form['preflight'] = array(
    '#type' => 'textfield',
		'#default_value' => 1,
		'#attributes' => array('class' => array('qms-hidden-field'),
                           'id' => 'qms-preflight-dr'),
  );
  $form['show_customer'] = array(
		'#type' => 'checkbox',
		'#title' => t('Show Customer'),
		'#default_value' => 1,
		'#attributes' => array('id' => 'qms-show-customer-chk'),
	);

  $form['markup_6'] = array(
		'#markup' => '</td><tr><td colspan="2"><br />',
	);
	//-----------------------------------------

  $date_opened_frmtd = date('Y-m-d H:i');

  $form['date_opened'] = array(
    '#type' => 'date_popup',
    '#title' => t('Date Opened'),
    '#size' => 14,
    '#date_format' => 'm-d-Y H:i',						// displayed format
      //default value has to be in this format
    '#default_value' => $date_opened_frmtd,
    '#required' => True,   // if no date entered, returns NULL
    '#attributes' => array('class' => array('qms-date-picker')),
    '#prefix' => '<div style="display:inline;">',
  );

  $form['date_closed'] = array(
		'#type' => 'date_popup',
		'#title' => t('Closed'),
		'#size' => 14,
		'#date_format' => 'm-d-Y H:i',						// displayed format
			//default value has to be in this format
		'#default_value' => '',
		'#required' => False,   // if no date entered, returns NULL
		'#attributes' => array('class' => array('qms-date-picker')),
		'#suffix' => '</div>',
	);


	// since date closed can appear in a number of different elements, enabled and disabled
	// we need to check its value from the browser and this is the only safe way to do it.
	// no need to format it, just store the unix time stamp value
	// only need to know if date_closed_verify > 0
	$form['date_closed_verify'] = array(
		'#type' => 'textfield',
		'#default_value' => 0,
		'#attributes' => array('class' => array('qms-hidden-field'),
														'id' => 'qms-date-closed-verify'),
	);



	global $action_list;

	$form['corrective_action'] = array(
		'#type' => 'select',
		'#title' => t('Corrective Action'),
		'#options' => $action_list->getList(CorrectiveActionList::DR),
		'#default_value' => 0,
		'#required' => False,
		'#attributes' => array('id' => 'qms-corrective-actions-select',
													 'class' => array('qms-corrective-actions-select')),
    //'#prefix' => '<tr><td>'
	);



  $form['markup_11'] = array(
		'#markup' => '</td></tr></table>',
	);




	//------------- ADD DISCREPANCY TEXTAREA  -----------

	$text_settings = array(
		'name' => 'discrepancy_text',
		'title' => t('Comments'),
		'text' =>	'',
		'required' => True,
		'disabled' => False,
	);

	_st_add_text_editor($form, $text_settings);


	//  -----------------------------------------



	$form['actions'] = array('#type' => 'actions');
	$form['actions']['submit'] = array(
		'#type' => 'submit',
		'#value' => t('Submit'),
    '#name' => 'submit',
		'#attributes' => array('class' => array('qms-btn-submit')),
	);

  $form['actions']['done'] = array(
		'#type' => 'button',
		'#value' => t('Done'),
    '#name' => 'done',
		'#attributes' => array('class' => array('qms-btn-done', 'qms-btn-extra'),
                           'onclick' => 'window.location="' . url($goto_url) .
                                        '"; return false;'),
	);


 //  $form['actions']['cancel'] = array(
 //    '#markup' => l(t('Done'), $goto_url),
 //  );


	// storage area for dynamic dialog elements
	$form['popup_dialog'] = array(
		'#type' => 'markup',
		'#markup' => '<div id="qms-message-box"></div>',
	);


	return $form;
}

/*
 *	discrepancy_preflight_form_validate()
 *
 *  Overloads hook_form_validate()
 *  Validation for the discrepancy_preflight_form
 */

function discrepancy_preflight_form_validate($form, $form_state) {

  // Only validate form if submit button clicked
  $button_clicked = $form_state['triggering_element']['#name'];

  if($form['actions']['submit']['#name'] != $button_clicked ){
    return $form;
  }

	$err_msg = 'Required fields missing.  ';

		if ( (int) $form_state['values']['simulator'] == 0 ) {
		form_set_error('simulator', t($err_msg . 'Simulator is a required field'));
	}

	/*
	if ( (int) $form_state['values']['chapter'] == 0 ) {
		form_set_error('chapter', t($err_msg . 'ATA Chapter is a required field'));
	}*/


	$dr_text = trim($form_state['values']['discrepancy_text_editor_value']);
	if ( $dr_text == '' ) {
		form_set_error('qms_discrepancy_text', t($err_msg . 'Preflight Requirement must be completed.'));
	}


	//----------------- date checking ---------------------

	// add seconds to make it DATE_ISO format:  'YYYY-MM-DD HH24:MI:SS'
	// date_opened may not always be present if the element is display only due to permission restrictions
	$date_opened = '';
	$idate_opened = 0;
	if ( isset($form_state['values']['date_opened']) ) {
		$date_opened = $form_state['values']['date_opened'];
		$idate_opened = _st_format_timestamp($date_opened);
		if ( $idate_opened == 0 ) {
			form_set_error('date_opened',
              t($err_msg . 'Date Opened is a required field'));
		}
	}

  $date_closed = ( isset($form_state['values']['date_closed']) ? $form_state['values']['date_closed'] : '' );
	$idate_closed = 0;
	if ( $date_closed <> '' ) {
		$idate_closed = _st_format_timestamp($date_closed);
	}

	if ( $idate_closed > 0 )  {
		if ( (int)$form_state['values']['corrective_action'] == 0 ) {
			form_set_error('corrective_action', t($err_msg . 'When Discrepancy is being closed, a Corrective Action is required.'));
		}

		// this is ok since you have to have edit permissions in order to be able to close a DR
		if ( ($idate_opened > 0) && ($idate_closed > 0) && ($idate_closed < $idate_opened)) {
			form_set_error('date_closed', t('Date Closed cannot be set to a date earlier than the Date Opened.'));
		}
	}
}


/*
 *	discrepancy_preflight_form_submit()
 *
 *  Overloads hook_form_submit()
 *  Final submit action for the discrepancy_form
 *  Stores input data to the db
 */

function discrepancy_preflight_form_submit($form, $form_state) {

  $button_clicked = $form_state['triggering_element']['#name'];

  if ( $form['actions']['submit']['#name'] == $button_clicked ){

    _create_discrepancy_report($form, $form_state);

  }
  else if ( isset($form['actions']['done']['#name']) &&
            ($form['actions']['done']['#name'] == $button_clicked) ) {

    $destination = drupal_get_destination();
    $goto_url = $destination['destination'];

    if( !strlen($goto_url) || ($goto_url == current_path()) ) {
      $goto_url = 'search/discrepancy';
    }
    drupal_goto($goto_url);

  }
}




/*
 *	_create_discrepancy_report()
 *
 *  Creates the discrepancy, comments, parts, and files records for a new DR
 */

function _create_discrepancy_report($form, $form_state) {

	$discrepancy = new stdClass();
	$comment = new stdClass();
	$part = new stdClass();
	$currtimestamp = REQUEST_TIME;
	$comment_list = array();
	$part_list = array();
	$file_list = array();
	$bError = False;

	global $user;

	// WYSIWYG EDITOR??  Is this feature enabled allowing for the editor
	//$ckeditor_activated  = variable_get(QMS_VAR_WYSIWYG_EDITOR, 1);  // if not set, default to ON



	// USER IS CUSTOMER?
	$user_is_customer_id = _user_is_customer($user->uid);


	if ( $user_is_customer_id ) {
		$discrepancy->tech_user_id = 0;
	}
	else {
		if ( user_access('assign discrepancy_technician') ) {
			// it's possible tech user could be 0
			$discrepancy->tech_user_id = ( isset($form_state['values']['tech']) ?
                                        (int) $form_state['values']['tech'] : 0 );
		}
		else {
			$discrepancy->tech_user_id = $user->uid;  // the currently logged-in user
		}
	}

  $baseno = $form_state['values']['dr_no'];
	$discrepancy->dr_no = _st_generate_report_no('DR', $baseno);

	// Simulator selected
	$discrepancy->simulator_id = ( isset($form_state['values']['simulator']) ? (int) $form_state['values']['simulator'] : 0 );
	$discrepancy->ata_chapter_id = ( isset($form_state['values']['chapter']) ? (int) $form_state['values']['chapter'] : 0 );
	$discrepancy->corrective_action_id =
          ( isset($form_state['values']['corrective_action']) ?
					(int) $form_state['values']['corrective_action'] : 0 );


	/*  The discrepancy text field is being updated to the $form['discrepancy_text_editor_value'] field
	**  whether the editor is enabled or not.  That is the field from which well will always get the value of
	**  discrepancy text, validate and save.
	**
	*/
	$discrepancy->discrepancy = _st_clean_ckeditor_text($form_state['values']['discrepancy_text_editor_value'],
																										QMS_TEXTAREA_MAX);

	$discrepancy->from_trouble_call_id = ( isset($form_state['values']['from_trouble_call_id']) ?
		(int) $form_state['values']['from_trouble_call_id'] : 0 );

	$discrepancy->show_customer = ( isset($form_state['values']['show_customer']) ?
																	(int) $form_state['values']['show_customer'] : 0 );

  $discrepancy->preflight = ( isset($form_state['values']['preflight']) ? 1 : 0 );
  if ( $discrepancy->preflight ) {
    $discrepancy->ata_chapter_id = QMS_ATACHAPTER_PREFLIGHT;
    $discrepancy->show_customer = 1;
  }


	// this flag will be handled by Engineering
	//$discrepancy->engineering = (int) $form_state['values']['engineering'];
	$discrepancy->faa = ( isset($form_state['values']['faa']) ? (int) $form_state['values']['faa'] : 0);
	$discrepancy->mmi = ( isset($form_state['values']['mmi']) ? (int) $form_state['values']['mmi'] : 0);
	$discrepancy->clear_time = ( isset($form_state['values']['clear_time']) ?
                                  (float) $form_state['values']['clear_time'] : 0);

  // need to update this date on create so it gets picked up in the 24/72hr reports
	$discrepancy->created_date = $currtimestamp;
	$discrepancy->updated_date = $currtimestamp;
	$discrepancy->created_by_user = $user->uid;
	$discrepancy->updated_by_user = $user->uid;

	$date_opened = trim($form_state['values']['date_opened']);
	$discrepancy->date_opened = _st_format_timestamp($date_opened);

	$date_closed = ( isset($form_state['values']['date_closed']) ? trim($form_state['values']['date_closed']) : '' );
	$discrepancy->date_closed = 0;
	if ( $date_closed <> '' ) {
		$discrepancy->date_closed = _st_format_timestamp($date_closed);
	}

	// These are hidden fields that don't get processed through the normal $form_state['values'] route
	// because of a Drupal bug involving hidden fields
	// For these data pieces only, we are bypassing drupal and going straight to the $_POST data

	/* Parts and comments, if input on the 'Add Discrepancy' screen, but not specifically added
	 * using the respective 'Add' buttons, will automatically be included in these '_to_add' lists on submit
	 */
	$cl = isset($_POST['comments_to_add']) ? $_POST['comments_to_add'] : '';
	$pl = isset($_POST['parts_to_add']) ? $_POST['parts_to_add'] : '';


	// parse the grouped fields (|-delimited) into individual records
	if ( strlen($cl) > 0 ) {
		$comment_list = explode('|', $cl);
		$discrepancy->has_comments = 1;
	}

	if ( strlen($pl) > 0 ) {
		$part_list = explode('|', $pl);
		$discrepancy->parts_used = 1;
	}

	/*
	if ( strlen($fl) > 0 ) {
		$file_list = explode('|', $fl);
		$discrepancy->files_attached = 1;
	}
	*/



	//----------------- Save to DB ------------------------

	// write new record
	// Table:  {qms_discrepancy_log}
	// $discrepancy->discrepancy_id will have a value after record is written
	if ( False == drupal_write_record('qms_discrepancy_log', $discrepancy) )
	{
		// something went wrong, record not saved
		$msg = 'Oops!  Something went wrong.  Discrepancy Report was not saved.';
		drupal_set_message(t($msg));
		drupal_goto('discrepancy/add');
	}
	else {
		$msg = 'Discrepancy Report ' . $discrepancy->dr_no . ' has been successfully added.';
		drupal_set_message(t($msg));
	}


  if ( count($comment_list) ) {
    // store comments
    $dr_comments = array();
    global $user;
    $comment->discrepancy_id = $discrepancy->discrepancy_id;
    $comment->user_id = $user->uid;  // currently logged in user
    $comment->name = $user->name;
    $comment->timestamp = $currtimestamp;
    $msg = '';
    foreach ($comment_list as $cmt) {
      // comment length is controlled from the browser, but if that fails for some reason, trim it here
      $comment->comment =  _st_clean_ckeditor_text($cmt, QMS_TEXTAREA_MAX);

      if ( False == drupal_write_record('qms_discrepancy_comments', $comment)) {
        $msg = 'Oops!  Something went wrong saving the Discrepancy comment record to the database.';
        $bError = True;
      }

      // add to comment record array
      $dr_comments[] = clone $comment;

      // record stored, clear unique fields in prep for next comment record to save
      unset($comment->discrepancy_comment_id);
      unset($comment->comment);
    }
    if ( $msg <> '' ) {
      drupal_set_message(t($msg));
    }
  }


  if ( count($part_list) ) {
    // store parts
    $dr_parts = array();
    $part->discrepancy_id = $discrepancy->discrepancy_id;
    $msg = '';
    foreach ($part_list as $p_rec) {
      $p_array = explode('~', $p_rec);

      $part->part_no = $p_array[0];
      $part->quantity = $p_array[1];
      $part->description = $p_array[2];
      $part->serial_number_in = $p_array[3];
      $part->serial_number_out = $p_array[4];

      if ( False == drupal_write_record('qms_discrepancy_parts', $part) ) {
        $msg = 'Oops!  Something went wrong saving the Discrepancy parts record to the database.';
      }

      // add to parts array
      $dr_parts[] = clone $part;

      // record stored, clear unique fields in prep for next comment record to save
      unset($part->part_id);
      unset($part->part_no);
      unset($part->quantity);
      unset($part->description);
      unset($part->serial_number_in);
      unset($part->serial_number_out);
      unset($p_array);
    }

    if ( $msg <> '' ) {
      drupal_set_message(t($msg));
    }
  }


	$goto_url = '';
	$add_files = (isset($form_state['values']['chk_add_file']) ?
                      (int)$form_state['values']['chk_add_file'] : 0 );

	if ( $add_files ) {
		/*	route to file upload form
		** Email Notifications will be sent after completion of File Upload Form
		** whether or not files are uploaded
		*/
    unset($_GET['destination']);
		$goto_url = 'discrepancy/file/add/' . $discrepancy->discrepancy_id;
	}
	else {
		if ( !$bError ) {
			// SEND EMAIL NOTIFICATIONS
			_discrepancy_add_update_post_processing($discrepancy->discrepancy_id);
		}
		$goto_url = 'discrepancy/edit/' . $discrepancy->discrepancy_id;
	}

	drupal_goto($goto_url);
}



/*
 *	_update_discrepancy_report()
 *
 *  Updates only the discrepancy report; comments, parts, files handled separately
 */

function _update_discrepancy_report($form, $form_state) {

	global $user;
	$discrepancy = (object) NULL;
	$currtimestamp = REQUEST_TIME;
	$bPartAdded = False;
	$bCommentAdded = False;

	$discrepancy->discrepancy_id = (int) $form_state['values']['discrepancy_id'];
	$dr_no = $form_state['values']['dr_no'];
	$add_files = (isset($form_state['values']['chk_add_file']) ? (int)$form_state['values']['chk_add_file'] : 0 );
	//$bReportChanged = (int)$form_state['values']['report_changed'];
	$bReportChanged = True;

	// check if comments or parts input, but not specifically added... if so, add them now  (only one of each)
	$comment = (object) Null;
	$comment->comment = _st_clean_ckeditor_text( $form_state['values']['comment_text_editor_value'], QMS_TEXTAREA_MAX );

	//watchdog('debugging', "comment object : " . var_export($comment));

	if ( strlen($comment->comment) ) {

    	$comment->discrepancy_comment_id = (int) $form_state['values']['comment_id'];
    	$comment->discrepancy_id = $discrepancy->discrepancy_id;
    	$comment->user_id = $user->uid;  // currently logged in user
    	$comment->timestamp = $currtimestamp;

		if ( $comment->discrepancy_comment_id == 0 ) {
			unset( $comment->discrepancy_comment_id );

			if ( False == drupal_write_record('qms_discrepancy_comments', $comment) ) {
				drupal_set_message(t('Oops!  Something went wrong saving the Discrepancy comment to the database.'));
			}
			else { $bCommentAdded = True; }
		}
		else {
			unset($comment->user_id);
			unset($comment->name);
			if ( False == drupal_write_record('qms_discrepancy_comments', $comment, 'discrepancy_comment_id') ) {
				drupal_set_message(t('Oops!  Something went wrong saving the Discrepancy comment to the database.'));
			}
			else { $bCommentAdded = True; }
		}

		$bReportChanged = True;
		$discrepancy->has_comments = 1;
	}

	// add part record if input
	$part = (object) Null;
	$part->part_no = trim($form_state['values']['part_no']);
	$part->quantity = (int) $form_state['values']['part_qty'];
	$part->description = trim($form_state['values']['part_description']);

	if ( strlen($part->part_no) && $part->quantity && strlen($part->description) ) {
    	$part->serial_number_in = trim($form_state['values']['serial_number_in']);
    	$part->serial_number_out = trim($form_state['values']['serial_number_out']);
    	$part->part_id = (int) $form_state['values']['part_id'];
    	$part->discrepancy_id = $discrepancy->discrepancy_id;

		if ( empty($part->part_id) ) {
			unset($part->part_id);
			if ( False == drupal_write_record('qms_discrepancy_parts', $part) ) {
				drupal_set_message(t('Oops!  Something went wrong saving the Discrepancy parts record to the database.'));
			}
			else { $bPartAdded = True; }
		}
		else {
			if ( False == drupal_write_record('qms_discrepancy_parts', $part, 'part_id') ) {
				drupal_set_message(t('Oops!  Something went wrong saving the Discrepancy parts record to the database.'));
			}
			else { $bPartAdded = True; }
		}
		$bReportChanged = True;
		$discrepancy->parts_used = 1;
	}



	//watchdog('debugging', "bReportChanged : " . $bReportChanged);
	if ( !$bReportChanged ) {
		// nothing changed in the DR, do not update... route
		if ( $add_files ) {
			// route to file upload form
     		unset($_GET['destination']);
			drupal_goto('discrepancy/file/add/' . $discrepancy->discrepancy_id);
		} else {
			if ( !empty($discrepancy->date_closed) && ( user_access('administer sabreQMS') == False)) {
				drupal_goto('search/discrepancy');
			} else {
				drupal_goto('discrepancy/edit/' . $discrepancy->discrepancy_id);
			}
		}
		return;
	}

	// USER IS CUSTOMER?
	$user_is_customer_id = _user_is_customer($user->uid);

	if ( isset($form_state['values']['tech']) ) {
		$discrepancy->tech_user_id = (int) $form_state['values']['tech'];
	}

	if ( ( !$user_is_customer_id ) && user_access('assign technician') ) {
		// it's possible this could be 0
		// this is populated by the $discrepancy->tech_user_id when the the form is built
		$discrepancy->orig_tech_user_id = ( isset($form_state['values']['orig_tech']) ? (int) $form_state['values']['orig_tech'] : 0 );
		// use these later in this function to send emails alerting about the tech assignment
	}

	$discrepancy->ata_chapter_id = (int) $form_state['values']['chapter'];
	$discrepancy->simulator_id = (int) $form_state['values']['simulator'];
	$discrepancy->corrective_action_id = (int) $form_state['values']['corrective_action'];
	$discrepancy->show_customer = (int) $form_state['values']['show_customer'];

	$discrepancy->discrepancy = _st_clean_ckeditor_text($form_state['values']['discrepancy_text_editor_value'], QMS_TEXTAREA_MAX);

	// Date Opened is permission dependent, may not show up on discrepancy form for editing
	if ( isset($form_state['values']['date_opened']) ) {
		$date_opened = trim($form_state['values']['date_opened']);
		$discrepancy->date_opened = _st_format_timestamp($date_opened);
	}

	// Date Closed is permission dependent, may not show up on discrepancy form for editing
	if ( isset($form_state['values']['date_closed']) ) {
		$date_closed = trim($form_state['values']['date_closed']);
		$discrepancy->date_closed = _st_format_timestamp($date_closed);
	}
	else {
		// no date closed value sent
		// check if admin and date_closed was previously set
		// if admin, and date_closed is empty, and original date_closed was not empty, clear the date closed
		if ( user_access('administer sabreQMS')                 &&
				 ((int)$form_state['values']['date_closed_verify'] > 0) )  {
					$discrepancy->date_closed = 0;
		}
	}

	//check dirty flag to see if this should be updated or not
	$dirty_flag = (int) $form_state['values']['faa_mmi_chg'];
	if ( $dirty_flag == True ) {
		$discrepancy->faa = (int) $form_state['values']['faa'];
		$discrepancy->mmi = (int) $form_state['values']['mmi'];
		$discrepancy->clear_time = (float) $form_state['values']['clear_time'];
	}

	$discrepancy->updated_date = $currtimestamp;
	$discrepancy->updated_by_user = $user->uid;

	//----------------- Save to DB ------------------------
	$msg = '';
	$bError = False;

	// update record
	// Table:  {qms_discrepancy_log}
	if ( drupal_write_record('qms_discrepancy_log', $discrepancy, 'discrepancy_id')) {
		$msg .= 'Discrepancy Report ' . $dr_no . ' has been successfully updated.';
		// Reload the cache
		// determine cache name
		$search = (object) Null;
		$key_cache_name = _get_qms_cache_name(QMS_DISCREPANCY_SEARCH_KEY);
		$key_cache = cache_get($key_cache_name);
		if ( isset($key_cache->data) && ($key_cache->data <> '') ) {
			$search = $key_cache->data;
			//refresh the cached disrepancy search results in the event of any changes may be displayed
			_get_discrepancy_search_results($search);
		}
		drupal_set_message(t($msg));
	}
	else {
		$bError = True;
		$msg = 'Oops!  There was a problem updating Discrepancy Report ' . $dr_no . '.';
		drupal_set_message(t($msg));
	}

	$add_files = (isset($form_state['values']['chk_add_file']) ? (int)$form_state['values']['chk_add_file'] : 0 );

	/*  // we have DRs controlled by field-level security... this is no longer necessary
	if ( isset($discrepancy->date_closed ) && ($discrepancy->date_closed > 0) &&
				( user_access('administer sabreQMS') == False)) {
		drupal_goto('search/discrepancy');
	}
	*/

	$goto_url = '';

	if ( $add_files ) {
		/*	route to file upload form
		 * Email Notifications will be sent after completion of File Upload Form
		 * whether or not files are uploaded
		 */
    	unset($_GET['destination']);
		$goto_url = 'discrepancy/file/add/' . $discrepancy->discrepancy_id;
	}
	else {
		//if ( !$bError ) {
			// SEND EMAIL NOTIFICATIONS
		//	_discrepancy_add_update_post_processing($discrepancy->discrepancy_id);
		//}
		$goto_url = 'discrepancy/edit/' . $discrepancy->discrepancy_id;
	}

	//watchdog('debugging', "bError : " . $bError);
	if ( !$bError ) {
		// SEND EMAIL NOTIFICATIONS
		_discrepancy_add_update_post_processing($discrepancy->discrepancy_id);
	}

	drupal_goto($goto_url);
}



/*
 *	_discrepancy_add_update_post_processing($discrepancy_id)
 *
 *	Called from add discrepancy, update discrepancy and file uploads.
 *
 *	Handles:
 *  	Email notifications
 *		Closing linked SD and TC reports
 */

function _discrepancy_add_update_post_processing($discrepancy_id = 0, $files_added = 0) {

	//watchdog('debugging', 'Got into the post processing function, did : '.$discrepancy_id);

  	if ( !$discrepancy_id ) { return; }  // something went wrong, exit

  	global $user;
	$updated_date = 0;
	$updated_by_user = $user->uid;


	// ------------- NOTIFICATIONS -----------------------
	// get ALL of the DR pieces
	// get the other parts of the discrepancy record for the email notifications
	$discrepancy = _get_discrepancy($discrepancy_id);
	$dr_comments = _get_discrepancy_comments($discrepancy_id);
	$dr_parts = _get_discrepancy_parts($discrepancy_id);
	$dr_files = _get_discrepancy_files($discrepancy_id);

	// This DR was just created
	if ( $discrepancy->created_date == $discrepancy->updated_date ) {
		// Notifications for New DRs

		// Determine the timestamp
    	// we will bump the updated_date timestamp by 1 second so that it will no longer exactly
    	// match the created date and will no longer trigger a "New Discrepancy" Notice
    	// but isn't significant to anything else
   	 	// file upload may have been cancelled
		$updated_date = (($files_added) ? time() : ($discrepancy->updated_date + 1));

		// Should notifications be sent for this simulator when a new DR is created?
		// get the list of emails that receive alerts
    	$notify_type = ($discrepancy->preflight ? QMS_NOTIFY_PREFLIGHT_NEW : QMS_NOTIFY_DISCREPANCY_NEW);
    	$email_title = ($discrepancy->preflight ? 'New Preflight Discrepancy Report' : 'New Discrepancy Report');
		$emails = _st_get_simulator_notification_email_list(QMS_APP, $discrepancy->simulator_id, $notify_type);

		// there are users to be notified about this new DR, send out the notification emails
		if ( strlen($emails) )
		{
			// format an email message to send out
			global $simulator_list;
			$subject = 'QMS NOTICE -- ' . $email_title . ' for ' .
                  $simulator_list->getName($discrepancy->simulator_id);
			$body = _notify_new_discrepancy_email($discrepancy, $dr_comments, $dr_parts, $dr_files);
			_st_send_drupal_email($discrepancy->discrepancy_id, $subject, $body, $emails);
		}
	}
	else {  // Notifications for Updated DRs

		//-------- Discrepancy Closed, TROUBLE CALLS && SIMULATOR DOWNTIME updates --------------------
		if ( isset($discrepancy->date_closed) && ( $discrepancy->date_closed > 0 ) && !$discrepancy->preflight ) {
			if ( $discrepancy->from_trouble_call_id ) {
				_close_trouble_call($discrepancy->from_trouble_call_id, $discrepancy->date_closed);
			}

			$dr_closed_emails = _st_get_simulator_notification_email_list(QMS_APP, $discrepancy->simulator_id, QMS_NOTIFY_DISCREPANCY_CLOSED);
			// there are users to be notified about this new DR, send out the notification emails
			if ( strlen($dr_closed_emails) > 0 )
			{
				// format an email message to send out
				global $simulator_list;
				$subject = 'QMS NOTICE -- Discrepancy Report Closed for ' . $simulator_list->getName($discrepancy->simulator_id);
				$body = _notify_closed_discrepancy_email($discrepancy, $dr_comments, $dr_parts, $dr_files);
				_st_send_drupal_email($discrepancy->discrepancy_id . '_clsd', $subject, $body, $dr_closed_emails);
					// in sabreQMS.utils.inc
			}

			//------ SIMULATOR DOWNTIME ---------
			// check if there is an attached simulator downtime record... if so, close it
			$num_rows = db_update('qms_simulator_downtime')
					->fields(array('in_date' => $discrepancy->date_closed))
					->condition('discrepancy_id', $discrepancy->discrepancy_id, '=')
					->condition('in_date', 0, '=')
					->execute();

			if ( $num_rows > 0 ) {
				// Simulator Downtime Report closed
				// reset the sim downtime search cache
				$search = (object) Null;
				$key_cache_name = _get_qms_cache_name(QMS_SIMULATORDOWNTIME_SEARCH_KEY);
				$key_cache = cache_get($key_cache_name);
				if ( isset($key_cache->data) && ($key_cache->data <> '') ) {
				$search = $key_cache->data;
				_get_simulator_downtime_search_list($search, True);
				}

				$sd_emails = _st_get_simulator_notification_email_list(QMS_APP,
																	$discrepancy->simulator_id,
																	QMS_NOTIFY_SIMULATOR_DOWNTIME);

				if ( strlen($sd_emails) ) {
				$sim_name = $simulator_list->getName($discrepancy->simulator_id);

				$subject = 'Simulator Status Change:  ' . $sim_name . ' is back in service.';
				$body = "Flight simulator, " . $sim_name . ", was placed back in service on " .
						_st_format_date($discrepancy->date_closed, "short") . ".";
				_st_send_drupal_email($discrepancy->discrepancy_id . '_sd', $subject, $body, $sd_emails);
				}
			}

		} else {  // Discrepancy has been updated, but not closed

			// get the list of emails that receive alerts
			$dr_update_emails = _st_get_simulator_notification_email_list( QMS_APP, $discrepancy->simulator_id, QMS_NOTIFY_DISCREPANCY_UPDATED);
			//watchdog('debugging', 'Emails to notify : ' . $dr_update_emails);

			// there are users to be notified about this DR, send out the notification emails
			if ( strlen($dr_update_emails) > 0 )
			{
				// format an email message to send out
				global $simulator_list;
				$subject = 'QMS NOTICE -- Discrepancy Report Updated for ' . $simulator_list->getName($discrepancy->simulator_id);
				$body = _notify_updated_discrepancy_email($discrepancy, $dr_comments, $dr_parts, $dr_files);
				_st_send_drupal_email($discrepancy->discrepancy_id . '_upd', $subject, $body, $dr_update_emails);   // in sabreQMS.utils.inc
			}

		}

		// check if emails need to be sent for tech assignment
		// if orig_tech_user_id field has been stored in the DR, then the assigned tech has been changed
		// send out an email notification
		if ( (isset($discrepancy->orig_tech_user_id)) && ($discrepancy->orig_tech_user_id > 0) && (user_access('assign technician') == True) ) {

			if ( isset($discrepancy->tech_user_id) && ($discrepancy->tech_user_id <> $discrepancy->orig_tech_user_id) ) {
				// tech user id has changed... we need to send notification emails
        		// to one or both techs + customer
				// format an email message to send out
				$subject = 'QMS NOTICE -- Discrepancy Technician/Instructor Assignment';
				$body = _format_body_technician_assignment_email($discrepancy, $dr_comments, $dr_parts, $dr_files);

				if ( $discrepancy->tech_user_id ) {
					$email = _st_get_user_email($discrepancy->tech_user_id);
					_st_send_drupal_email($discrepancy->discrepancy_id . '_' . $discrepancy->tech_user_id, $subject, $body, $email); // in sabreQMS.utils.inc
				}
				if ( $discrepancy->orig_tech_user_id ) {
					$email = _st_get_user_email($discrepancy->orig_tech_user_id);
					_st_send_drupal_email($discrepancy->discrepancy_id . '_' . $discrepancy->orig_tech_user_id, $subject, $body, $email);
				}
				// now notify the customer or whomever created the DR
				$email = _st_get_user_email($discrepancy->created_by_user);
				_st_send_drupal_email($discrepancy->discrepancy_id . '-' . $discrepancy->created_by_user, $subject, $body, $email);
			}
		}

		// Determine the timestamp
		if ($files_added) {  //update the timestamp
			$updated_date = time();
		}
		else {		// nothing uploaded, keep the same timestamp from the Edit-save
			$updated_date = $discrepancy->updated_date;
			$updated_by_user = $discrepancy->updated_by_user;
		}
	}

	// UPDATE the DR Timestamps,
	// Clear the $orig_tech_user_id field now that notices have been processed
	$num_rows = db_update('qms_discrepancy_log')
								->fields(array(
										'orig_tech_user_id' => 0,
										'updated_date' => $updated_date,
										'updated_by_user' => $updated_by_user,
										))
								->condition('discrepancy_id', $discrepancy->discrepancy_id, '=')
								->execute();
}



/*
 *   Only if Assign Technician feature is enabled in the system
 *
 *	_format_body_technician_assignment_email()
 *
 */

function _format_body_technician_assignment_email($discrepancy, $dr_comments, $dr_parts, $dr_files) {

	$body =
		'<h2><strong>Discrepancy ' . $discrepancy->dr_no . ' Technician Assignment</strong></h2>' .
		'<hr />' .
		'<p>This discrepancy has been assigned to <strong>' . _get_user_name($discrepancy->tech_user_id) . '</strong>.</p>' .
		'<hr />';

	$body .= _format_discrepancy_report_for_email($discrepancy, $dr_comments, $dr_parts, $dr_files);

	return $body;
}

/*
 *
 *
 *	_notify_new_discrepancy_email()
 *
 */

function _notify_new_discrepancy_email($discrepancy, $dr_comments, $dr_parts, $dr_files) {

	$email = _st_get_user_email($discrepancy->created_by_user);  // this may return '' if created_by_user==0
	$user_link = ( strlen($email) ? l(_get_user_name($discrepancy->created_by_user), 'mailto:' . $email) : _get_user_name($discrepancy->created_by_user) );

	$body =
		'<h2><strong>New Discrepancy</strong></h2>' .
		'<hr />' .
		'<p>This discrepancy was created:  <br />' .
		( $discrepancy->created_by_user ? $user_link . ', ' : '' ) .
		( $discrepancy->created_date ? _st_format_date($discrepancy->created_date, 'medium') : '') .
		'</p>' .
		'<hr />';

	$body .= _format_discrepancy_report_for_email($discrepancy, $dr_comments, $dr_parts, $dr_files);

	return $body;
}


/*
 *
 *
 *	_notify_updated_discrepancy_email()
 *
 */

function _notify_updated_discrepancy_email($discrepancy, $dr_comments, $dr_parts, $dr_files) {

	$email = _st_get_user_email($discrepancy->updated_by_user);  // this may return '' if updated_by_user==0
	$user_link = ( strlen($email) ? l(_get_user_name($discrepancy->updated_by_user), 'mailto:' . $email) : _get_user_name($discrepancy->updated_by_user) );

	$body =
		'<h2><strong>Discrepancy Updated</strong></h2>' .
		'<hr />' .
		'<p>This discrepancy was updated:  <br />' .
		( $discrepancy->updated_by_user ? $user_link . ', ' : '' ) .
		( $discrepancy->updated_date ? _st_format_date($discrepancy->updated_date, 'medium') : '') .
		'</p>' .
		'<hr />';

	$body .= _format_discrepancy_report_for_email($discrepancy, $dr_comments, $dr_parts, $dr_files);

	return $body;
}


/*
 *
 *
 *	_notify_closed_discrepancy_email()
 *
 */

function _notify_closed_discrepancy_email($discrepancy, $dr_comments, $dr_parts, $dr_files) {

	$email = _st_get_user_email($discrepancy->updated_by_user);  // this may return '' if updated_by_user==0
	$user_link = ( strlen($email) ? l(_get_user_name($discrepancy->updated_by_user), 'mailto:' . $email) : _get_user_name($discrepancy->updated_by_user) );

	$body =
		'<h2><strong>Discrepancy Closed</strong></h2>' .
		'<hr />' .
		'<p>This discrepancy was closed:  <br />' .
		( $discrepancy->updated_by_user ? $user_link . ', ' : '' ) .
		( $discrepancy->updated_date ? _st_format_date($discrepancy->updated_date, 'medium') : '') .
		'</p>' .
		'<hr />';

	$body .= _format_discrepancy_report_for_email($discrepancy, $dr_comments, $dr_parts, $dr_files);

	return $body;
}




/*
 *   Format the discrepancy report information for email
 *
 *	_format_discrepancy_report_for_email()
 *
 */

function _format_discrepancy_report_for_email($discrepancy, $dr_comments, $dr_parts, $dr_files) {


	///////////////////////////////////////////////
	// format the contents of the DR for email  //
	///////////////////////////////////////////////
	global $chapter_list;
	global $simulator_list;


	// DR Header Information
	$body =
		'<table>' .
		'<tr><td colspan="2"><h2><strong>' . $discrepancy->dr_no . '</strong></h2></td></tr>' .
		'<tr><td><strong>Technician/Instructor</strong></td><td>' .
         _get_user_name($discrepancy->tech_user_id) . '</td></tr>' .
		'<tr><td><strong>Simulator</strong></td><td>' .
         $simulator_list->getName($discrepancy->simulator_id) . '</td></tr>' .
		'<tr><td><strong>ATA Chapter</strong></td><td>' .
         $chapter_list->getName($discrepancy->ata_chapter_id) . '</td></tr>' .
		'<tr><td><strong>Date Opened</strong></td><td>' .
         _st_format_date($discrepancy->date_opened, 'short') . '</td></tr>' .
		'<tr><td><strong>Engineering</strong></td><td>' .
         ($discrepancy->engineering ? 'Yes' : 'No') . '</td></tr>';
    '<tr><td><strong>Prev. Maint.</strong></td><td>' .
         ($discrepancy->is_pm ? 'Yes' : 'No') . '</td></tr>';
    '<tr><td><strong>Preflight</strong></td><td>' .
         ($discrepancy->preflight ? 'Yes' : 'No') . '</td></tr>';

	if ( $discrepancy->faa || $discrepancy->mmi ) {
		$body .=
			'<tr><td><strong>FAA/MMA</strong></td><td>' .
          ($discrepancy->faa ? 'FAA' : '') .
          ($discrepancy->mmi ? 'MMI' : '') .
					(($discrepancy->clear_time > 0) ? (' (' . $discrepancy->clear_time . 'days)') : '' ) .
			'</td></tr>';
	}

	// DR Text
	$body .=
		'<tr><td colspan="2">&nbsp;</td></tr>' .
		'<tr><td colspan="2"><h3><strong>Discrepancy</strong></h3></td></tr>' .
		'<tr><td colspan="2">' . $discrepancy->discrepancy . '</td></tr>' .
		'<tr><td colspan="2">&nbsp;</td></tr>';

	// DR Comments
	if ( count($dr_comments) ) {
		$body .=
			'<tr><td colspan="2">&nbsp;</td></tr>' .
			'<tr><td colspan="2"><h3><strong>Comments</strong></h3></td></tr>';

		foreach ( $dr_comments as $cmt ) {
			$body .= '<tr><td colspan="2">' . $cmt->name . ' - ' . _st_format_date($cmt->timestamp, 'short') . '<hr />' .
										$cmt->comment . '</td></tr>' .
							 '<tr><td colspan="2">&nbsp;</td></tr>';
		}
	}

	// DR Parts
	if ( count($dr_parts) ) {
		$body .=
			'<tr><td colspan="2">&nbsp;</td></tr>' .
			'<tr><td colspan="2"><h3><strong>Parts</strong></h3></td></tr>';

		foreach ( $dr_parts as $pt ) {
			$body .=
        '<tr><td><strong>Part No.:   </strong></td><td>' . $pt->part_no . '</td></tr>' .
         '<tr><td><strong>Quantity:   </strong></td><td>' . $pt->quantity . '</td></tr>' .
         '<tr><td><strong>Description:</strong></td><td>' . $pt->description . '</td></tr>' .
         '<tr><td><strong>S/N In:</strong></td><td>' . $pt->serial_number_in . '</td></tr>' .
         '<tr><td><strong>S/N Out:</strong></td><td>' . $pt->serial_number_out . '</td></tr>' .
         '<tr><td colspan="2">&nbsp;</td></tr>';
		}
	}

	// DR Files
	if ( count($dr_files) ) {
		$body .=
			'<tr><td colspan="2">&nbsp;</td></tr>' .
			'<tr><td colspan="2"><h3><strong>Files</strong></h3></td></tr>' .
			'<tr><td colspan="2">You must log into the QMS to access the associated files</td></tr>';

		foreach ( $dr_files as $f ) {
			$body .= '<tr><td><strong>Uploaded:   </strong>' .
                $f->name . ' - ' . _st_format_date($f->uploaded_timestamp, 'short') . '</td><td>' .
								$f->file_name . '</td></tr>' .
							 '<tr><td colspan="2">&nbsp;</td></tr>';
		}
	}

	// End of DR
	$body .= '</table>';

	return $body;
}



/*
 *	discrepancy_delete_confirm()
 *
 *  Delete the discrepancy report -- ADMIN ONLY
 */

function discrepancy_delete_confirm($form, $form_state, $discrepancy_id) {

	$bAdmin = user_access('administer sabreQMS');

	if ( $bAdmin == False ) {
		drupal_set_message(t('Administrator permissions required to delete a discrepancy report.'));
		drupal_goto('discrepancy/edit/' . $discrepancy_id);
		return;
	}

	// get the dr_no
	$discrepancy = array();
	$result = db_query("SELECT dr_no, date_closed FROM {qms_discrepancy_log}
                      WHERE discrepancy_id = :did",
										array(':did' => $discrepancy_id));
	$discrepancy = $result->fetchObject();

	/*
	if ( $discrepancy->date_closed ) {
		drupal_set_message(t('Unable to delete ' . $discrepancy->dr_no . '.  The DR has already been closed.'));
		drupal_goto('discrepancy/edit/' . $discrepancy_id);
		return;
	}
	*/


	// check for engineering links
	$sql = "SELECT engineering_id FROM {qms_engineering} WHERE discrepancy_id = :did LIMIT 1";
	$result = db_query($sql, array(':did' => $discrepancy_id));
	if ( $result->rowCount() > 0 ) {
			drupal_set_message(t('Unable to delete ' . $discrepancy->dr_no . '.  It is linked to an engineering record.'));
			drupal_goto('discrepancy/edit/' . $discrepancy_id);
			return;
	}

	// check for simulator_downtime links
	$sql = "SELECT simulator_downtime_id FROM {qms_simulator_downtime} WHERE discrepancy_id = :did LIMIT 1";
	$result = db_query($sql, array(':did' => $discrepancy_id));
	if ( $result->rowCount() > 0 ) {
			drupal_set_message(t('Unable to delete ' . $discrepancy->dr_no . '.  It is linked to a simulator downtime record.'));
			drupal_goto('discrepancy/edit/' . $discrepancy_id);
			return;
	}

	// store the discrepancy_id and dr_no in hidden fields for the next step
	// storage field for the discrepancy_id (edit) -- hidden
	$form['discrepancy_id'] = array(
		'#type' => 'textfield',
		'#default_value' => $discrepancy_id,
		'#attributes' => array('id' => 'qms-discrepancy-id',
														'class' => array('qms-hidden-field')),
	);
	// storage field for the discrepancy_id (edit) -- hidden
	$form['dr_no'] = array(
		'#type' => 'textfield',
		'#default_value' => $discrepancy->dr_no,
		'#attributes' => array('id' => 'qms-dr-no',
														'class' => array('qms-hidden-field')),
	);

  $title = t('Delete Discrepancy') . '?';
  $question = t('Are you sure you want to delete?') .
              '<h2>' . $discrepancy->dr_no . '</h2><br />' .
              t('This action cannot be undone.');
  $goto_if_canceled = 'discrepancy/edit/' . $discrepancy_id;
  $yes_btn = 	t('Delete');
  $no_btn = t('Cancel');

  // force this here to avoid a problem with routing if cancelled
  $_GET['destination'] = 'search/discrepancy';

  return confirm_form($form, $title,	$goto_if_canceled, $question,
                      $yes_btn, $no_btn);

}

/*
 *	discrepancy_delete_confirm_submit()
 *
 *  overloads:  hook_confirm_submit()
 *  Delete the discrepancy -- ADMIN ONLY
 */
function discrepancy_delete_confirm_submit($form, $form_state) {
	if ($form_state['values']['confirm']) {
		$discrepancy_id = $form_state['values'] ['discrepancy_id'];
		$dr_no = $form_state['values']['dr_no'];

		$num_rows = db_delete('qms_discrepancy_parts')
					->condition('discrepancy_id', $discrepancy_id, '=')
					->execute();

		$num_rows = db_delete('qms_discrepancy_comments')
					->condition('discrepancy_id', $discrepancy_id, '=')
					->execute();

		// DELETE DISCREPANCY FILES

		// need to delete physical files on the server
		// in addition to the db references


		// are there any shift log files?  We just need one for this discrepancy in order to delete the DR's file directory
		$results = db_query('SELECT file_id, file_uri FROM {qms_discrepancy_files} f WHERE discrepancy_id = :did LIMIT 1',
												array(':did' => $discrepancy_id));


		if ( $results->rowCount() ) {
			$file_rec = $results->fetchObject();

			// deletes the physical files from their server location
			_delete_all_attached_files($file_rec->file_uri);


			// delete all of the DR's files from database
			$num_rows = db_delete('qms_discrepancy_files')
						->condition('discrepancy_id', $discrepancy_id)
						->execute();
		}

		// Now delete the DR itself
		$num_rows = db_delete('qms_discrepancy_log')
					->condition('discrepancy_id', $discrepancy_id, '=')
					->execute();

		$msg = ( ($num_rows == 1) ? $dr_no . ' has been deleted.' : 'Error occurred deleting' . $dr_no . '.');
		drupal_set_message($msg, 'status');

		// remove the discrepancy search results, but leave the search key so that the list gets refreshed
		// leave the search key cache intact

		// Reload the cache

		// determine cache name
		$search = (object) Null;
		$key_cache_name = _get_qms_cache_name(QMS_DISCREPANCY_SEARCH_KEY);

		$key_cache = cache_get($key_cache_name);
		if ( isset($key_cache->data) && ($key_cache->data <> '') ) {
			$search = $key_cache->data;

			// refresh the cached search results to reflect any changes
			_get_discrepancy_search_results($search);
		}

	}
	drupal_goto('search/discrepancy');
}

/*
 *	dr_no_autocomplete()
 *
 *  Ajax Callback Handler for the DR No fields AutoComplete on inpus
 */

function dr_no_autocomplete($string) {
	$matches = array();
	$result = db_query("SELECT dr_no FROM {qms_discrepancy_log}
											WHERE date_closed = 0 AND dr_no LIKE UPPER (:str)",
											array(':str' => $string . '%'));

	foreach($result as $row) {
		// don't use discrepancy id no's her.  The autocomplete widget acts strangely with ids.
		// match on the text on submit
		$matches[$row->dr_no] = check_plain($row->dr_no);
	}
	return drupal_json_output($matches);
}

/*
 *	get_dr_simulator()
 *
 *  Ajax Callback Handler for the DR Simulator Name once a DR has been specified
 */

function get_dr_simulator() {

	$content = '';

	$dr_no = trim($_POST['dr_no']);

	if ( strlen($dr_no) == 12 )
	{
	$result = db_query("SELECT simulator_id
                      FROM {qms_discrepancy_log} d
                      WHERE d.dr_no = :drno",
											array(':drno' => $dr_no));

		if ( $result->rowCount() == 1 ) {
			$simulator_id = $result->fetchField();
      global $simulator_list;
      $content = $simulator_list->getName($simulator_id);
		}
	}
	die($content);
}

/*
 *	get_dr_text()
 *
 *  Ajax Callback Handler for the DR Text (display in floating box along DR search list)
 */
/*
function get_dr_text($discrepancy_id) {

	$content = '';

	//$discrepancy_id = (int)$_POST['discrepancy_id'];

	if ( $discrepancy_id )
	{
		$result = db_query("SELECT discrepancy FROM {qms_discrepancy_log} d
												WHERE discrepancy_id = :did",
												array(':did' => $discrepancy_id));

		if ( $result->rowCount() == 1 ) {
			$content = $result->fetchField();
		}
	}
	if ( strlen($content) > 650 ) {
		$content = _st_convert_symbols(substr($content, 0, 650)) . '...';
	}
	die($content);  // only show 1st 650 chars
}
*/

/*
 * _get_discrepancy($discrepancy_id)
 * Returns and object pointing to the discrepancy record data
 */

function _get_discrepancy($discrepancy_id) {
	$discrepancy = (object) Null;


	$sql = "SELECT discrepancy_id, dr_no, tech_user_id, orig_tech_user_id,
          ata_chapter_id, simulator_id, discrepancy, corrective_action_id,
          date_opened, date_closed, faa, mmi,
          clear_time, parts_used, files_attached,
          has_comments, show_customer, engineering, is_pm, preflight,
          from_trouble_call_id, from_sch_assignment_id,
          qtg_event_id, qtg_test_id,
          created_date, created_by_user, updated_date, updated_by_user
					FROM {qms_discrepancy_log} d
					WHERE discrepancy_id = :did";
	$result = db_query($sql, array(':did' => $discrepancy_id));

	if ( $result->rowCount() ) {
		$discrepancy = $result->fetchObject();
	}
	return $discrepancy;
}



/*
 * _get_discrepancy_linked_reports($discrepancy)
 * Returns an array of this DR's associated ENGs and SDs and TCs
 */

function _get_discrepancy_linked_reports($discrepancy, $route_url = '') {
  try {

    $links = array();

    // if adding a new DR, there is no discrepancy id, but we still need to
    // handle the TC link below
    if ( isset($discrepancy->discrepancy_id) && $discrepancy->discrepancy_id ) {

      // get associated ENGs
      $sql = "SELECT engineering_id, eng_no
              FROM {qms_engineering} e
              WHERE discrepancy_id = :did
              ORDER BY datetime ASC";
      $result = db_query($sql, array(':did' => $discrepancy->discrepancy_id));

      if ( $result->rowCount() ) {
        foreach ($result as $row) {
          $links[] = l( $row->eng_no, 'engineering/view/' . $row->engineering_id,
                        array('query' => array('destination' => $route_url))
                        );
        }
      }

      // get associated SD
      $sql = "SELECT simulator_downtime_id, sd_no
              FROM {qms_simulator_downtime} s
              WHERE discrepancy_id = :did
              ORDER BY updated_date ASC";
      $result = db_query($sql, array(':did' => $discrepancy->discrepancy_id));

      if ( $result->rowCount() ) {
        foreach ($result as $row) {
          $links[] = l( $row->sd_no, 'simulator_downtime/view/' . $row->simulator_downtime_id,
                        array('query' => array('destination' => $route_url))
                        );
        }
      }
    }

    // get associated TC
    if ( isset($discrepancy->from_trouble_call_id) && $discrepancy->from_trouble_call_id ) {

      // include the associated TC (only one possible), if there is one included in the DR itself
      // we have a linked TC report which initiated this DR

      $sql = "SELECT tc_no FROM {qms_trouble_call_log} WHERE trouble_call_id = :tcid";
      $result = db_query($sql, array(':tcid' => $discrepancy->from_trouble_call_id));

      if ( $result->rowCount() ) {
        $tc_no = $result->fetchField();
        $links[] = l( $tc_no, 'troublecall/view/' . $discrepancy->from_trouble_call_id,
                      array('query' => array('destination' => $route_url))
                    );
      }
    }


    // get associated QTG
    if ( isset($discrepancy->qtg_event_id) && $discrepancy->qtg_event_id ) {

      // we have a linked QTG Test Failure which initiated this DR

      $sql = "SELECT qtg_no FROM {qms_qtg_events} WHERE qtg_event_id = :id";
      $result = db_query($sql, array(':id' => $discrepancy->qtg_event_id));

      if ( $result->rowCount() ) {
        $qtg_no = $result->fetchField();
        $links[] = l( $qtg_no,
                      'qtg/test/status/view/' .
                       $discrepancy->qtg_event_id . '/' .
                       $discrepancy->qtg_test_id,
                      array('query' => array('destination' => $route_url))
                    );
      }
    }


    return $links;
  }
	catch(Exception $e) {
		watchdog('sabreQMS', '_get_discrepancy_linked_reports()' . $e->getMessage(),
            array(), WATCHDOG_ERROR);
	}
}



/*
 * _get_qtg_discrepancy_links($qtg_event_id, $qtg_test_id)
 * Returns an array of DR links for this test event
 */

function _get_qtg_discrepancy_links($qtg_event_id, $qtg_test_id, $route_url = '') {

  try {

    $links = array();

    // get associated QTG
    if ( $qtg_event_id && $qtg_test_id ) {

      // we have a linked QTG Test Failure which initiated this DR

      $sql = "SELECT discrepancy_id, dr_no
              FROM {qms_discrepancy_log}
              WHERE qtg_event_id = :eid
              AND   qtg_test_id = :tid
              ORDER BY created_date ASC";
      $result = db_query($sql, array(
                                  ':eid' => $qtg_event_id,
                                  ':tid' => $qtg_test_id,
                                ));

      if ( $result->rowCount() ) {
        $dr_list = $result->fetchAll();

        foreach($dr_list as $dr) {
          $links[] = l( $dr->dr_no, 'discrepancy/view/' . $dr->discrepancy_id,
                        array('query' => array('destination' => $route_url))
                      );
        }
      }
  }
    return $links;
	}
	catch(Exception $e) {
		watchdog('sabreQMS', '_get_qtg_discrepancy_links()' . $e->getMessage(),
            array(), WATCHDOG_ERROR);
	}
}


