/* 

 Purpose: Validation for Bupa Invoicing
 Author: Alan A Henderson (AH)
 		 Andre Olivier (AO)
 Date: 12 July 2002
 
 Each function will return a string. either:
 	ok - if it passes the criteria OR
	string - the string to be included in the error message box
	
 ------------------------------------------------------------------------	
 Functions:
 	clearSessions() - (AO) called when a users resets the form
	setFocus() - (AH) focus onto the current form and create a pointer to it
  	ExpressionChecker() - (AH) pass in a string and a regular expression - does it match? boolean return
	ValidateCons() - (AO) This validates the cosultant search for blank entries and parses to search page otherwise
	ValidateFormTCode() - (AO) validate the treatment code searches
	ValidateFormTDesc() - (AO) validate the treatment description searches
	ValidateCons() - (AO) check the controling specialist name is valid before searching.
	ValidateFormHosp() - (AO) validate the hospital searches
	DateDDMMYYYYCompare(sDateOne,sDateTwo) - (AH) checks that date one is previous to date two - date formats MUST be: DD/MM/YYYY	
	DateCheck(sDate,sFuture) - (AH) pass in a date which checks for valid format, and whether it is a future date or not
	FormValidate() - (AH) controls the validation of the whole form.
*/

// global variables
var sForm;
var dCurrDate;
var undef;
var sValidFee = "^\\d{1,}\\.\\d{2}$";
var g_cSeparator = "#";

function isNull(sVal) {
	if (sVal == undef || sVal.length == 0) {
		return true;
	} else {
		return false;
	}
}

// called when a users resets the form
function clearSessions() {
	self.location.href='/includes/asp/killsessions.asp?intSession=1';
}

// called when the page loads first of all. sets focus on invoice number
function setFocus() 	{
		sForm = document.frmInvoicing; // pointer to the form - cut down on code
		sForm.frminvoicenr.focus();
}

function RoundNumb(iNumb,iRoundTo) {
// rounds a given number to X decimal places, defaults to 2 - for currency reasons
	iRoundTo = (!iRoundTo ? 2 : iRoundTo); // check we have a value
	return Math.round(iNumb*Math.pow(10,iRoundTo))/Math.pow(10,iRoundTo);
}

function ExpressionChecker(sString, sExpression) {
	// takes in a string, and a regular expression - tests the two and returns boolean

	Reg = new RegExp(sExpression,"i") 
	return (Reg.test(sString)) // pretty simple really
}

function ValidateCons() {
	// This validates the cosultant search for blank entries and 
	// parses to search page otherwise
	var sContrName = sForm.frmcontrname.value
	
	if (isNull(sContrName)) {
		alert("Please enter a valid Consultant Name... Thank you.");
		sForm.frmcontrname.focus();
	} else {
	 	var wSearchWin = window.open('/asp/invoicing/results_consultant.asp?strCons='+escape(sContrName),'Results','width=465,height=400,scrollbars=yes');
	 	 	wSearchWin.focus;
 	}
}

function ValidateFormTCode(){
	//  validate the treatment code searches
	var sTreatCode = sForm.frmtreatcode.value;
	
	if (isNull(sTreatCode)) {
		alert("Enter a valid Treatment Code... Thank you.");
		sForm.frmtreatcode.focus();
	} else {
		var wSearchWin = window.open('/asp/invoicing/results_ICD9_code.asp?strTreatCode='+escape(sTreatCode),'Results','width=420,height=400,scrollbars=yes');
	 		wSearchWin.focus;
	}
}

function ValidateFormTDesc() {
	//  validate the treatment description searches
	var sTreatDesc = sForm.frmtreatdesc.value;
		
	if (isNull(sTreatDesc)) {
		alert("Enter the condition requiring treatment... Thank you.");
		sForm.frmtreatdesc.focus();
	} else {
		var wSearchWin = window.open('/asp/invoicing/results_ICD9_desc.asp?strTreatDesc='+escape(sTreatDesc),'Results','width=420,height=400,scrollbars=yes');
 			wSearchWin.focus;
 	}
}

function ValidateFormHosp() {
	//  validate the hospital searches
	var sHosp = sForm.frmtreatpos.value;
	
	if (isNull(sHosp)) {
		alert("Enter a valid Treatment Place of Service... Thank you.");
		sForm.frmtreatpos.focus();
	} else {
	 	var wSearchWin = window.open('/asp/invoicing/results_hospital.asp?strPlace='+escape(sHosp),'Results','width=420,height=400,scrollbars=yes');
	 	 	wSearchWin.focus;
 	} 	
} 	

function ValidateFormPDesc(iNumb, oTextBox) {
	// validate the procedure descriptions
	var sVal = oTextBox.value; // get its current value
	
	if(isNull(sVal)) {
		alert("Enter a valid Procedure Description... Thank you.");
		oTextBox.focus();
	} else {
		var wSearchWin = window.open('/asp/invoicing/results_OPCS_'+iNumb+'desc.asp?strProcDesc='+sVal,'Results','width=420,height=400,scrollbars=yes');
 	 		wSearchWin.focus;
 	}
}

function ValidateFormPCode(iNumb, oTextBox) {
	// validate the procedure codes
	var sVal = oTextBox.value; // get its current value

	if(isNull(sVal)) {
		alert("Enter a valid Procedure Code... Thank you.");
		oTextBox.focus();
	} else {
	 	var wSearchWin = window.open('/asp/invoicing/results_OPCS_'+iNumb+'code.asp?strProcCode='+sVal,'Results','width=420,height=400,scrollbars=yes');
 	 		wSearchWin.focus;
 	}
}


function isWhitespace(s) {
    var whitespace = " \t\n\r";
    var i;

    if (isEmpty(s)) return true; // s is empty
    
    // Search through string's characters one by one until we find a non-whitespace character.
    // When we do, return false; if we don't, return true.
    for (i=0; i<s.length; i++) {   
        if (whitespace.indexOf(s.charAt(i)) == -1) return false;
    }
    return true;     // All characters are whitespace.
}


function isEmpty(s) { // Check whether string s is empty.
    return ((s == null) || (s.length == 0))
}


function isValidName(s) {
    var i
    if (isWhitespace(s)) 
        if (isValidName.arguments.length == 1) return false;
        else return (isValidName.arguments[1] == true);

    for(i=0; i<s.length; i++) {
        if (!((s.charCodeAt(i)>=65 && s.charCodeAt(i)<=90) || 
              (s.charCodeAt(i)>=97 && s.charCodeAt(i)<=122) || 
              s.charCodeAt(i)==45 || 
              s.charCodeAt(i)==46 || 
              s.charCodeAt(i)==39 || 
              s.charCodeAt(i)==32)) return false;
    }
    return true;
}


function isValidNumber(s) {
    var i
    if (isWhitespace(s)) 
        if (isValidNumber.arguments.length == 1) return false;
        else return (isValidNumber.arguments[1] == true);

  for(i=0; i<s.length; i++) {
        if (!(s.charCodeAt(i)>=48 && s.charCodeAt(i)<=57)) 
           return false;
    }
    return true;
}


function parseFee(oFee) {
	// check the format of the fee - must be XXXX.XX
	// If it is null then that is ok.
	// If is it not null then is it in the correct format.
	// Passed in a textbox object	
	var sCurrVal = oFee.value; // current value
	
	if (isNull(sCurrVal)) {
		return false; // its ok
	} else {
		// is it in the correct format?
		if (ExpressionChecker(sCurrVal,sValidFee)) {
			return true; // its ok
		} else { // its not quite right

			var sRegTestOneDigit = "^\\d{1,}\\.\\d{1}$";  // one digit after decimal?
			var sRegTestPeriod = "^\\d{1,}\\.$"; // decimal at the end?
			var sRegTestDigit = "^\\d{1,}$"; // digits but no decimal?
			var sRegTestPeriodOneDigit = "^\\.\\d$";
			var sRegTestPeriodTwoDigit = "^\\.\\d{2}$";
	
			sCurrVal = parseFloat(sCurrVal);

			// perform the tests
				
			if (ExpressionChecker(sCurrVal,sRegTestOneDigit) && sCurrVal > 0) {
				oFee.value += "0";
				return false;
			} else if (sCurrVal <= 0 ){
				alert('Zeros is not a valid fee, please re-enter');
				return false;
			} else if (ExpressionChecker(sCurrVal,sRegTestPeriod) && sCurrVal > 0){
				oFee.value += "00";		
				return false;
			} else if (ExpressionChecker(sCurrVal,sRegTestDigit) && sCurrVal > 0){
				oFee.value += ".00";
				return false;
			} else if (ExpressionChecker(sCurrVal,sRegTestPeriodOneDigit) && sCurrVal > 0){
				oFee.value = "0" + oFee.value + "0";
				return false;		
			} else if (ExpressionChecker(sCurrVal,sRegTestPeriodTwoDigit) && sCurrVal > 0){
				oFee.value = "0" + oFee.value;
				return false;								
			} else {
				alert('Invalid Fee, please re-enter');
				return false;
			}
		}
	}
	
	return true;
}

// Start, Kumar Gaurav,HPOV 299552,22/12/2008
function check()
{
if((event.keyCode > 47 && event.keyCode < 58) || (event.keyCode==46))
{
return;
}
else
{
alert('please enter numeric value');
event.returnValue = null; 
}
}
// End, Kumar Gaurav,HPOV 299552,22/12/2008



function DateDDMMYYYYCompare(sDateOne,sDateTwo) {
	// so we can validate both dates - must be in DD/MM/YYYY format
	// checks to see if sDateOne < sDateTwo
	var bOK = true;

		if(DateCheck(sDateOne,false)=='ok' && DateCheck(sDateTwo,false)=='ok') { // check for format 
			// split up the dates and check them
				// DATE ONE
				var tempDateOne,tempDateTwo
				var arDateOne = sDateOne.split('/');
					sDateOneDay = parseFloat(arDateOne[0]);
					sDateOneMon = parseFloat(arDateOne[1]);
					sDateOneYr = parseFloat(arDateOne[2]);
					
				// DATE TWO
				var arDateTwo = sDateTwo.split('/');
					sDateTwoDay = parseFloat(arDateTwo[0]);
					sDateTwoMon = parseFloat(arDateTwo[1]);
					sDateTwoYr = parseFloat(arDateTwo[2]);
					tempDateOne = new Date(sDateOneYr,sDateOneMon - 1,sDateOneDay )		
					tempDateTwo = new Date(sDateTwoYr,sDateTwoMon - 1,sDateTwoDay )		

					if(tempDateOne > tempDateTwo) 
						bOK = false;

			// pass back whatever...
			sRetVal = bOK;				
		} else {
			sRetVal = false;
		}
				
	return(sRetVal)
}

function DateCheck(sDate,bFuture) {
	/* check the format of a the date:
		- check the length
		- split it by "/"
			- make sure each part... is numeric
			- get the month 
				- make sure the day is available in the month i.e. No 30th of Feb
			- check the year
		
		Also... if sFuture is TRUE then
			- check the year is <= this year
			- check the month is <= this month in this year
			- check the day is <= this day, in this month, in this year
	*/

    //create a lookup for months. - not including february - leap year consideration
    var arDateLookup = { '01' : 31,'03' : 31, '04' : 30,'05' : 31,'06' : 30,'07' : 31,
                        '08' : 31,'09' : 30,'10' : 31,'11' : 30,'12' : 31}	

		// DATE FORMAT CHECK aiming for DD/MM/YYYY
		var Reg = /^\d{2}\/\d{2}\/\d{4}$/
		var sMsg = 'ok';  // what we will return

		// test the string with the expression
		if (Reg.test(sDate)) {  // the format is ok

			var bDateOK = false;
			var arDate = sDate.split('/');  // make an array so we can get the day,month,year

		    var intDay = parseFloat(arDate[0]); 		// get the day
		    var intMonth =(arDate[1]); 	// get the month
//			if (intMonth.length == 1) { intMonth = "0" + intMonth; }
		    var intYear = parseFloat(arDate[2]); 		// get the year			
			//check if month value and day value agree
		    if(!isNull(arDateLookup[intMonth])) {
		      if(intDay <= arDateLookup[intMonth] && intMonth != 00) {
		        bDateOK = true; //found in lookup table, date is ok.
			  }
		    } else if (intMonth > 12 || intMonth == 00) { // most likely february
			      bDateOK = false; //invalid month
			} else {
				//check for February - leap year considerations
			    if( ((intYear % 4 == 0 && intDay <= 29) || (intYear % 4 != 0 && intDay <=28)) && intDay !=0) {
			      bDateOK = true; //valid number of days			
				}
			}
			
			if (!bDateOK) {
				sMsg = "is an invalid date";
			} else if (bDateOK && bFuture) {  // we need to check the date is not a future date.
				if (!DateDDMMYYYYCompare(sDate,dCurrDate)) {
					sMsg = "future dates not allowed";
				}
			}
			
		} else {
			sMsg = "not in the correct format (dd/mm/yyyy)";
		}

		return (sMsg);
}


function FormValidate(bSubmit) {

	/* handles the validation of the whole form. 
		Calls all other functions, and deals with the results of them.
		bSubmit = BOOLEAN. 
			- TRUE - submit the form upon successful validation
			- FALSE - confirm everything is ok and calculate the totals if required.
	*/
	
	var sRetVal = ""; // the value we will get back from each function
	var sMsg = ''; 		// the message we will pass back
	var bErr = false; // no errors so far...
	
	dCurrDate = sForm.frmCurrentDate.value; // the current date: DD/MM/YYYY

	// Header of error message
	var sMsg = 'Sorry, there were errors within the form, please correct and re-submit.\n ------------------------------------------------------------------------------------------------ \n\n'; 
		
	// 1: Check the FORM date
		// Required & must be valid date, not future date.
		var sFormDate = sForm.frmdate.value;
			sRetVal = DateCheck(sFormDate,true);  // check for format and not a future date
		
			if (sRetVal != 'ok') { // there was an error
				bErr = true;
				sMsg = sMsg + "- Date:\t\t " + sRetVal + "\n";
			}
			
	// 2: Invoice number
		// Required
		var sInvoiceNo = sForm.frminvoicenr.value;
			if (isNull(sInvoiceNo)) {
				bErr = true;
				sMsg = sMsg + "- Invoice No:\t must be entered\n";
			}
	
	// ----------------------- PATIENT DETAILS ------------------------
	var sMsgHeaderPatients = "\n--- Patient Details ---\n"
	var bPatientError = false;
	var sPatientErr = ''; // patient errors - will be appended to main message if there are errors

	// 3: Patient Name
		// Required
		var sPatientSurName = sForm.frmpatSurname.value;
			if (isNull(sPatientSurName)) {
			 	bPatientError = true;
				sPatientErr = sPatientErr + "- Surname:\t\t must be entered\n";
			}
			if (!isValidName(sPatientSurName)) {
			 	bPatientError = true;
				sPatientErr = sPatientErr + "- Please enter valid Surname\n";
			}

			
		var sPatientForeName = sForm.frmpatForename.value;
			if (isNull(sPatientForeName)) {
			 	bPatientError = true;
				sPatientErr = sPatientErr + "- Forename:\t\t must be entered\n";
			}			
			if (!isValidName(sPatientForeName)) {
			 	bPatientError = true;
				sPatientErr = sPatientErr + "- Please enter valid Forename\n";
			}


	
	// 4: Address - first line
		// Required
		var sAddr = sForm.frmpataddress1.value;
			if (isNull(sAddr)) {
				bPatientError = true;
				sPatientErr = sPatientErr + "- Address 1:\t must be entered\n";
			}
			
	// 5: Post code
		// Required, and must be in correct post code format
		var sPostCode = sForm.frmpatpostcode.value;
		var	bPcodeErr = false;		
		var bCodeFormatOK = false;
		// possible post code formats - from royal mail
		var	sPcodeExpr = "^[A-Z]\\d\\s\\d[A-Z]{2}$,^[A-Z]\\d{2}\\s\\d[A-Z]{2}$,^[A-Z]{2}\\d\\s\\d[A-Z]{2}$,^[A-Z]{2}\\d{2}\\s\\d[A-Z]{2}$,^[A-Z]\\d[A-Z]\\s\\d[A-Z]{2}$,^[A-Z]{2}\\d\[A-Z]\\s\\d[A-Z]{2}$,^[A-Z]{3}\\s\\d[A-Z]{2}$"
		/*'AN NAA', 'ANN NAA', 'AAN NAA', 'AANN NAA', 'ANA NAA', 'AANA NAA', 'AAA NAA'	-- (A = A-Z, N = 0-9) */		
		
		var arPcodeExpr = sPcodeExpr.split(',');
		var sExpr;

			if (isNull(sPostCode)) {
				bPatientError = true;
				sPatientErr = sPatientErr + "- Postcode:\t must be entered\n";			
			} else {
				// loop through each expression in the array
				for (sExpr in arPcodeExpr) {
					if (ExpressionChecker(sPostCode,arPcodeExpr[sExpr])) {
						var bCodeOK = true;			
					}
				}
				
				// check if there was an error
				if (!bCodeOK) {
					bPatientError = true
					sPatientErr = sPatientErr + "- Postcode:\t invalid format \n";
				}
				
			}

	// 6: Patient Date of Birth
		// Required & must be valid date, not future date.
		var sPatDob = sForm.frmpatdob.value;
		var bValidPatDOB = false ;
			sRetVal = DateCheck(sPatDob,true);  // check for format and not a future date		
			if (sRetVal != 'ok') { // there was an error
				bPatientError = true;
				sPatientErr = sPatientErr + "- DOB:\t\t " + sRetVal + "\n";
			}
			else
				bValidPatDOB = true;

	// 6: Patient Sex
		// Required, must be selected
		var sPatSex = sForm.frmpatsex[sForm.frmpatsex.selectedIndex].value;
			if (isNull(sPatSex)) {
				bPatientError = true;
				sPatientErr = sPatientErr + "- Sex:\t\t must be selected\n";			
			}
	
	// 7: Patient Registration Number
		// Required, must be 10 digits long ending in a zero
		var sPatRegNo = sForm.frmpatregnr.value;	
		var sExpr = "^\\d{10}(d{1})?$"	// must be 10 digits in length, ending in a zero
			if (isNull(sPatRegNo)) {
				bPatientError = true;
				sPatientErr = sPatientErr + "- Reg No:\t\t must be entered\n";
			} else {
				if (!isValidNumber(sPatRegNo)) {
					bPatientError = true;
					sPatientErr = sPatientErr + "- Reg No:\t\t invalid number\n";			
				}
				/*		
				if (!ExpressionChecker(sPatRegNo,sExpr)) {
					bPatientError = true;
					sPatientErr = sPatientErr + "- Reg No:\t\t invalid number format\n";			
				}
				*/
				
				/* Added below validation for HP call 269534 , Dt. 16/10/2008
				   Registration number '0000000000' will no longer be accepted */
				/*Added radix 10 in parseInt function to avoid problem with Reg num starting with zero,
				  HP Call 288897,Dt. 25/11/2008 */
				else if(parseInt(sPatRegNo,10)==0){
				    bPatientError = true;
					sPatientErr = sPatientErr + "- Reg No:\t\t invalid number\n";
			    }  
			    /*End - HP call 269534 changes */ 
			}
	
	// 8: Pre-authorisation number 
		// Not required, if entered must be 8 digits only
		var sPatPreAuthNo = sForm.frmpatprereg.value;	
		var sExpr = "^\\d{8}$"	// must be 8 digits in length
			if (isNull(sPatPreAuthNo)) {
			 // this is ok, it is not required
			} else { // check its in the correct format
				if (!ExpressionChecker(sPatPreAuthNo,sExpr)) {
					bPatientError = true;
					sPatientErr = sPatientErr + "- Pre-auth No:\t invalid format - 8 numeric characters\n";			
				}
			}
	
	// any patient errors?
	if (bPatientError) {	
		bErr = true;
		sMsg = sMsg + sMsgHeaderPatients + sPatientErr 	
	}


	// ----------------------- TREATMENT DETAILS ------------------------
	var sMsgHeaderTreat = "\n--- Treatment Details ---\n"
	var bTreatError = false;
	var sTreatErr = ''; // Treatment errors - will be appended to main message if there are errors

	// 9: Description
		// Required
		var sTreDesc = sForm.frmtreatdesc.value;	
			if (isNull(sTreDesc)) {
				bTreatError = true;
				sTreatErr = sTreatErr + "- Description:\t must be entered\n";
			} 

	 if(sTreDesc.length  > 200 )
	   {
		sTreDesc = sTreDesc.substr(0,200)
		sForm.frmtreatdesc.value = sTreDesc
	   }	
	   
	// 10: Code
		// Required
		var sTreCode = sForm.frmtreatcode.value;	
			if (isNull(sTreCode)) {
				bTreatError = true;
				sTreatErr = sTreatErr + "- Code:\t\t must be entered\n";
			} 
	
	// TREATMENT DATES
		// The following two fields are related so we get their values now. used in both checks.	
		var sTreFirstSymp = sForm.frmtreatsympdate.value; // first symptom
		var bValidFirstSymp = false;
		var sTreFirstVisit = sForm.frmtreatgpdate.value;  // first visit
		var bValidFirstVisit = false;
		
	// 11: First Symptom Date
		// Not required, if entered - must be before First GP date 
			if (isNull(sTreFirstSymp) || sTreFirstSymp == 'dd/mm/yyyy') {
				// this ok, not required
			} else {
				sRetVal = DateCheck(sTreFirstSymp,true);  // check for format and not a future date		
				
				if (sRetVal != 'ok') { // there was an error
					bTreatError = true;
					sTreatErr = sTreatErr + "- First Symptom:\t " + sRetVal + "\n";
				} else {
					bValidFirstSymp = true;
				}
			}

	  if (bValidFirstSymp && bValidPatDOB){	         
			if (!DateDDMMYYYYCompare(sPatDob,sTreFirstSymp)) { // checks if the first date is less than the second date.
				bTreatError = true;
				sTreatErr = sTreatErr + "- Date of first symptom cannot be before patient's date of birth\n";
			}
		 }		
	     	
		
	// 12: First GP Visit
		// Not required, if entered - must be after First symptom date 
		
			if (isNull(sTreFirstVisit) || sTreFirstVisit == 'dd/mm/yyyy') {
				// this ok, not required
			} else {
				sRetVal = DateCheck(sTreFirstVisit,true);  // check for format and not a future date		
				
				if (sRetVal != 'ok') { // there was an error
					bTreatError = true;
					sTreatErr = sTreatErr + "- First Visit:\t " + sRetVal + "\n";
				} else {
					bValidFirstVisit = true;
				}
			}	
			
			
	 if (bValidFirstVisit && bValidPatDOB){	         
	   if (!DateDDMMYYYYCompare(sPatDob,sTreFirstSymp)) { // checks if the first date is less than the second date.
	   	bTreatError = true;
	   	sTreatErr = sTreatErr + "- Date of first GP visit cannot be before patient's date of birth\n";
	   }
	 }		

	// 11 & 12 together
		// If both dates are entered then the First GP Visit date must be later than the First Sympton date.
		if (bValidFirstSymp && bValidFirstVisit) {
			if (!DateDDMMYYYYCompare(sTreFirstSymp,sTreFirstVisit)) { // checks if the first date is less than the second date.
				bTreatError = true;
				sTreatErr = sTreatErr + "- Date of first visit cannot be before date first of symptom\n";
			}
		}

	// any treatment errors?
	if (bTreatError) {	
		bErr = true;
		sMsg = sMsg + sMsgHeaderTreat + sTreatErr 	
	}

	// ----------------------- CONTROLLING SPECIALIST ------------------------
	var sMsgHeaderContr = "\n--- Controlling Specialist ---\n"
	var bContrError = false;
	var sContrErr = ''; // Controlling Specialist errors - will be appended to main message if there are errors
	
	// NO VALIDATION REQUIRED AS YET
	var scontrname = sForm.frmcontrname.value
	var scontrgmcnr = sForm.frmcontrgmcnr.value
	var scontrprovnr = sForm.frmcontrprovnr.value
	
	if(isNull(scontrname))
	  {
		bContrError = true;
		sMsgHeaderContr += "\t- Name:\t\t must be entered\n";
	  }
	  
	if(isNull(scontrprovnr))
	  {
		bContrError = true;
		sMsgHeaderContr += "\t- Provider number:\t\t must be entered\n";
	  }	  
	else
	   {
	    if(isNaN(scontrprovnr))
	      {
		   bContrError = true	
	       sMsgHeaderContr += "\t- Provider number:\t\t Invalid format\n" ;
	      }
	   }  

	// any controlilng specialist errors?
	if (bContrError) {	
		bErr = true;
		sMsg = sMsg + sMsgHeaderContr + sContrErr 	
	}

	// ----------------------- FOR TREATMENT AT ------------------------
	var sMsgHeaderForTA = "\n--- For Treatment At ---\n"
	var bForTAError = false;
	var sForTAErr = ''; // For Treatment AT errors - will be appended to main message if there are errors
	var strEpSetting1 = sForm.frmEpSetting1.options[sForm.frmEpSetting1.selectedIndex].value
	var strEpSetting2 = sForm.frmEpSetting1.options[sForm.frmEpSetting2.selectedIndex].value	
	var strEpSetting3 = sForm.frmEpSetting1.options[sForm.frmEpSetting3.selectedIndex].value
	var strAdmdate = sForm.frmAddmissiondate.value
	var strDisdate = sForm.frmDischargedate.value
	var bAdmDateMand = false
	var bValidAdmDate = false
	var bValidDiscDate = false
	var bProvNoMand = false
	var bInPatient = false
	var bDayCase = false 
	//alert(getKey(strEpSetting1)+"\n"+getKey(strEpSetting2)+"\n"+getKey(strEpSetting3)+"\n"+strAdmdate+"\n"+strDisdate)
	
	var sTreAt = sForm.frmtreatpos.value;	
    if(sTreAt.length  > 120 )
	   {
		sTreAt = sTreAt.substr(0,120)
		sForm.frmtreatpos.value = sTreAt
	   }		
	
    
	
	if ( getKey(strEpSetting1) == 'I' || getKey(strEpSetting1) == 'D' || 
		 getKey(strEpSetting2) == 'I' || getKey(strEpSetting2) == 'D' || 		
		 getKey(strEpSetting3) == 'I' || getKey(strEpSetting3) == 'D'  	
		) 
	 	 bAdmDateMand = true ;
	
	if ( getKey(strEpSetting1) == 'I' || getKey(strEpSetting1) == 'D' || getKey(strEpSetting1) == 'O' ||
		 getKey(strEpSetting2) == 'I' || getKey(strEpSetting2) == 'D' || getKey(strEpSetting2) == 'O' ||		
		 getKey(strEpSetting3) == 'I' || getKey(strEpSetting3) == 'D' || getKey(strEpSetting3) == 'O' 	
		) 	
	   bProvNoMand = true ;	
	
	
	if(bProvNoMand && isNull(sForm.frmtreatprovnr.value))
	  {
		 sForTAErr +="\t Please enter Bupa Provider number\n"
		 bForTAError = true;				   	 
	   }	 		 
		 		
	if (bAdmDateMand && isNull(strAdmdate))
	   {
		 sForTAErr +="\t Please enter the admission date\n"
		 bForTAError = true;				   	 
	   }	 
	   
	if(! isNull (strAdmdate) )
	{	
		sRetVal = DateCheck(strAdmdate,true);  // check for format and not a future date
		if (sRetVal != 'ok') { // there was an error
			bForTAError = true;
			sForTAErr += "\t\t- Admission date : " + sRetVal + "\n";
		   }
		else
		    bValidAdmDate = true ;   
		
	}
			
	if(! isNull(strDisdate))
	 {
		sRetVal = DateCheck(strDisdate,true);  // check for format and not a future date
		if (sRetVal != 'ok') { // there was an error
			bForTAError = true;
			sForTAErr += "\t\t- Discharge date : " + sRetVal + "\n";
			}			 
		else
		   bValidDiscDate = true;	
	 }	
	 
	 if (bValidAdmDate  && bValidPatDOB){	         
			if (!DateDDMMYYYYCompare(sPatDob,strAdmdate)) { // checks if the first date is less than the second date.
				bForTAError = true;
				sForTAErr +=  "- Date of admission cannot be before patient's date of birth\n";
			}
		}		    		 
	 
		// If both dates are entered then the First GP Visit date must be later than the First Sympton date.
	if (bValidAdmDate && bValidDiscDate) {
		if (!DateDDMMYYYYCompare(strAdmdate,strDisdate)) { // checks if the first date is less than the second date.
			bForTAError = true;
			sForTAErr += "- Discharge date cannot be before date of admission\n";
		}
	}	 	 
	
	
	  	   
	 	 
	if ( getKey(strEpSetting1) == 'I' ||  getKey(strEpSetting2) == 'I' ||  getKey(strEpSetting3) == 'I') 	
		bInPatient = true;
		 	 
	if ( getKey(strEpSetting1) == 'D' ||  getKey(strEpSetting2) == 'D' ||  getKey(strEpSetting3) == 'D') 			 	 
		bDayCase = true ;
  		
	if (bDayCase && bInPatient)
	  {
		 sForTAErr +="\t There can only be an Episode Setting of Inpatient or Daycase on an invoice.\n"
		 bForTAError = true;				   	 
	   }	
	   
	   
	// any controlilng specialist errors?
	if (bForTAError) {	
		bErr = true;
		sMsg += sMsgHeaderForTA + sForTAErr 	
	}	
	  	 
	// ----------------------- PROCEDURES ------------------------
	var sMsgHeaderProc = "\n--- Procedures ---\n"
	var bProcError1 = false;
	var bProcError2 = false;
	var bProcError3 = false;		
	var bValidsP1Date = false ;
	var bValidsP2Date = false ;
	var bValidsP3Date = false ;
	
	
	var sProcErr = ''; // Procedures errros - will be appended to main message if there are errors
	
	// Maximum of 3 procedures will be entered.
	var sProc1Err = '';
	var sProc1Hdr = 'Procedure 1\t- all fields must be complete';
	var sProc2Err = '';
	var sProc2Hdr = 'Procedure 2\t- all fields must be complete';
	var sProc3Err = '';
	var sProc3Hdr = 'Procedure 3\t- all fields must be complete';
	
		// Procedure 1 - REQUIRED: DATE(valid format,not furture), PROCEDURE, CODE & FEE(valid XX.XX)
		var sP1Date = sForm.frmtreat1date.value;
		var sP1Proc = sForm.frmtreat1proc.value;
		var sP1Code = sForm.frmtreat1code.value;
		var sP1Fee = sForm.frmtreat1fee.value;
	
		var strServiceType1 = sForm.frmServiceType1.options[sForm.frmServiceType1.selectedIndex].value
		var strAdm1date = sForm.frmAddmissiondate.value
		var strDis1date = sForm.frmDischargedate.value
		
		
		if (isNull(sP1Date) || isNull(sP1Proc) || isNull(sP1Code) || isNull(sP1Fee) || isNull(strEpSetting1) || isNull(strServiceType1) ) {
			bProcError1 = true;			
		} else { // they have all been filled in... validate them all
			// date
			sRetVal = DateCheck(sP1Date,true);  // check for format and not a future date
			if (sRetVal != 'ok') { // there was an error
				bProcError1 = true;
				sProc1Err += "\t\t- Date: " + sRetVal + "\n";
			}
			else
			  bValidsP1Date = true;
			  

		if (bValidsP1Date  && bValidPatDOB){	         
				if (!DateDDMMYYYYCompare(sPatDob,sP1Date)) { // checks if the first date is less than the second date.
					bProcError1 = true;
					sProc1Err += "- Date for Procedure 1 cannot be before patient's date of birth\n";
				}	    		 
		  }	
		  
	   if ((getKey(strEpSetting1) == 'I' || getKey(strEpSetting1) == 'D' ) && bValidAdmDate  && bValidsP1Date){	         
			if (!DateDDMMYYYYCompare(strAdmdate,sP1Date)) { // checks if the first date is less than the second date.
				bProcError1 = true;
				sProc1Err +=  "- Date for Procedure 1 cannot be before the admission date\n";
			}
		}		    		 	   		  		  
			
		if(sP1Proc.length  > 200 )
			   {
				sP1Proc = sP1Proc.substr(0,200)
				sForm.frmtreat1proc.value = sP1Proc
			   }					
			
			
			// Start, Kumar Gaurav,HPOV 299552,22/12/2008
			if(isNaN(sForm.frmtreat1fee.value))
			{
			bProcError1 = true;
			//alert('Fee Field 1 :Not a number, Please enter numeric value');
			sProc1Err += "\t\t- Fee Should be number only\n";
			}
			// End, Kumar Gaurav,HPOV 299552,22/12/2008
			
			
			// procedure and code should be alright - no special format required.

			sP1Fee = parseInt(sP1Fee);
			// fee: must be valid 
			if (isNull(sP1Fee)) {
				bProcError1 = true;
				sProc1Err += "\t\t- Fee must be entered\n";							
			} else if (!ExpressionChecker(sP1Fee,sValidFee) && sP1Fee <= 0) {
				bProcError1 = true;
				sProc1Err += "\t\t- Fee is an invalid format\n";				
			}
			

		    if(isNull(strEpSetting1) ){
				bProcError1 = true;
				sProc1Err += "\t\t- Episode setting for Procedure 1 must be selected\n";							
			 }
			 					
		    if(isNull(strServiceType1)){
				bProcError1 = true;
				sProc1Err += "\t\t- The type of service for Procedure 1 must be selected\n";							
			 }		     
		    			
		}	
		
		// Add to the full procedure error
		if (bProcError1) {
			sProcErr += sProc1Hdr + "\n" + sProc1Err;
			bErr = true;			
		}
	
		// Procedure 2 - NOT REQUIRED: if entered... DATE(valid format,not furture), PROCEDURE, CODE & FEE(valid XX.XX)
		var sP2Date = sForm.frmtreat2date.value;
		var sP2Proc = sForm.frmtreat2proc.value;
		var sP2Code = sForm.frmtreat2code.value;
		var sP2Fee = sForm.frmtreat2fee.value;

		var strServiceType2 = sForm.frmServiceType1.options[sForm.frmServiceType2.selectedIndex].value
		var strAdm2date = sForm.frmAdm2date
		var strDis2date = sForm.frmDis2date		
		
		if (isNull(sP2Date) && isNull(sP2Proc) && isNull(sP2Code) && isNull(sP2Fee) && isNull(strEpSetting2) && isNull(strServiceType2) ) {
			// this is ok - they are allowed to be null. If one is entered then they must all be entered.
		} else { // they have all been filled in... validate them all
			// date
			if (isNull(sP2Date)) {  // not allowed - must be entered
				bProcError2 = true;
				sProc2Err += "\t\t- Date must be entered \n";
			} else {
				sRetVal = DateCheck(sP2Date,true);  // check for format and not a future date
				if (sRetVal != 'ok') { // there was an error
					bProcError2 = true;
					sProc2Err += "\t\t- Date: " + sRetVal + "\n";
					}
				else
				  bValidsP2Date = true;

				if (bValidsP2Date  && bValidPatDOB){	         
						if (!DateDDMMYYYYCompare(sPatDob,sP2Date)) { // checks if the first date is less than the second date.
							bProcError2 = true;
							sProc2Err +=  "- Date for Procedure 2 cannot be before patient's date of birth\n";
						}	    		 
					}	
					
					
				if ((getKey(strEpSetting2) == 'I' || getKey(strEpSetting2) == 'D' ) && bValidAdmDate  && bValidsP2Date){	         
						if (!DateDDMMYYYYCompare(strAdmdate,sP2Date)) { // checks if the first date is less than the second date.
							bProcError2 = true;
							sProc2Err +=  "- Date for Procedure 2 cannot be before the admission date\n";
						}
					}		    		 	   		  		  					
					
				
			}
			
			if(sP2Proc.length  > 200 )
			   {
				sP2Proc = sP2Proc.substr(0,200)
				sForm.frmtreat2proc.value = sP2Proc
			   }								
			
			// procedure and code must be entered
			if (isNull(sP2Proc)) { // PROCEDURE
					bProcError2 = true;
					sProc2Err += "\t\t- Procedure must be entered\n";
			}

			if (isNull(sP2Code)) { // CODE
					bProcError2 = true;
					sProc2Err += "\t\t- Code must be entered\n";
			}			
             
             // Start, Kumar Gaurav,HPOV 299552,22/12/2008
			if(isNaN(sForm.frmtreat2fee.value))
			{
			bProcError2 = true;
			//alert('Fee Field 2 : Not a number, Please enter numeric value');
			sProc2Err += "\t\t- Fee Should be number only\n";
			}
			// End, Kumar Gaurav,HPOV 299552,22/12/2008
             
             
             
			sP2Fee = parseInt(sP2Fee);

			// fee: must be valid 
			if (!ExpressionChecker(sP2Fee,sValidFee) && sP2Fee <= 0) {
				bProcError2 = true;
				sProc2Err += "\t\t- Fee is an invalid format\n";				
			}
			

		    if(isNull(strEpSetting2) ){
				bProcError2 = true;
				sProc2Err += "\t\t- Episode setting for Procedure 2 must be selected\n";							
			 }
			 					
		    if(isNull(strServiceType2)){
				bProcError2 = true;
				sProc2Err += "\t\t- The type of service for Procedure 2 must be selected\n";							
			 }		     
		    
			
			// Add to the full procedure error
			if (bProcError2) {
				sProcErr += sProc2Hdr + "\n" + sProc2Err
				bErr = true;				
			}	
			
		}			

		// Procedure 3 - NOT REQUIRED: if entered... DATE(valid format,not furture), PROCEDURE, CODE & FEE(valid XX.XX)
		var sP3Date = sForm.frmtreat3date.value;
		var sP3Proc = sForm.frmtreat3proc.value;
		var sP3Code = sForm.frmtreat3code.value;
		var sP3Fee = sForm.frmtreat3fee.value;

		var strServiceType3 = sForm.frmServiceType1.options[sForm.frmServiceType3.selectedIndex].value
		var strAdm3date = sForm.frmAdm3date
		var strDis3date = sForm.frmDis3date		
		
		if (isNull(sP3Date) && isNull(sP3Proc) && isNull(sP3Code) && isNull(sP3Fee) && isNull(strEpSetting3) && isNull(strServiceType3) ) {
			// this is ok - they are allowed to be null. If one is entered then they must all be entered.
		} else { // they have all been filled in... validate them all
			// date
			if (isNull(sP3Date)) {  // not allowed - must be entered
				bProcError3 = true;
				sProc3Err += "\t\t- Date must be entered \n";
			} else {
				sRetVal = DateCheck(sP3Date,true);  // check for format and not a future date
				if (sRetVal != 'ok') { // there was an error
					bProcError3 = true;
					sProc3Err += "\t\t- Date: " + sRetVal + "\n";
				}
				else
				  bValidsP3Date = true;

				if (bValidsP3Date && bValidPatDOB){	         
						if (!DateDDMMYYYYCompare(sPatDob,sP3Date)) { // checks if the first date is less than the second date.
							bProcError3 = true;
							sProc3Err += "- Date for Procedure 3 cannot be before patient's date of birth\n";
						}
				   }			    		 				
				   
				if ((getKey(strEpSetting3) == 'I' || getKey(strEpSetting3) == 'D' ) && bValidAdmDate  && bValidsP3Date){	         
						if (!DateDDMMYYYYCompare(strAdmdate,sP3Date)) { // checks if the first date is less than the second date.
							bProcError3 = true;
							sProc3Err +=  "- Date for Procedure 3 cannot be before the admission date\n";
						}
					}		    		 	   		  		  									   
			}
			
			// procedure and code must be entered
			if (isNull(sP3Proc)) { // PROCEDURE
					bProcError3 = true;
					sProc3Err += "\t\t- Procedure must be entered\n";
			}

			if(sP3Proc.length  > 200 )
			   {
				sP3Proc = sP3Proc.substr(0,200)
				sForm.frmtreat3proc.value = sP3Proc
			   }					
		   
		   
			if (isNull(sP3Code)) { // CODE
					bProcError3 = true;
					sProc3Err += "\t\t- Code must be entered\n";
			}	
			
			// Start, Kumar Gaurav,HPOV 299552,22/12/2008
			if(isNaN(sForm.frmtreat3fee.value))
			{
			bProcError3 = true;
			//alert('Fee Field 3: Not a number, Please enter numeric value');
			sProc3Err += "\t\t- Fee Should be number only\n";
			}
			// End, Kumar Gaurav,HPOV 299552,22/12/2008
			
			
			
			sP3Fee = parseInt(sP3Fee);		

			// fee: must be valid 
			if (!ExpressionChecker(sP3Fee,sValidFee) && sP3Fee <= 0) {
				bProcError3 = true;
				sProc3Err += "\t\t- Fee is an invalid format\n";
			}
			
			
		    if(isNull(strEpSetting3) ){
				bProcError3 = true;
				sProc3Err += "\t\t- Episode setting for Procedure 3 must be selected\n";							
			 }
			 					
		    if(isNull(strServiceType3)){
				bProcError3 = true;
				sProc3Err += "\t\t- The type of service for Procedure 3 must be selected\n";							
			 }		     
		    
			// Add to the full procedure error
			if (bProcError3) {
				sProcErr += sProc3Hdr + "\n" + sProc3Err
				bErr = true;				
			}
		}
		
		if (bProcError1 || bProcError2 || bProcError3) {  // were there errors with any of these?
			sMsg += sMsgHeaderProc + sProcErr
			bErr = true;			
		}

	   /*if (sP1Date == sP2Date && sP1Code == sP2Code)
		  {
		  bErr = true;
		  sMsg+="\tAll the procedure dates should be different\n"		  
		  }	
	   
		  
       if(sP1Code != "" && (sP1Date == sP2Date  || sP1Date == sP3Date || sP2Date == sP3Date) && !(sP2Date == "" && sP3Date == ""))
		 {
		  bErr = true;
		  sMsg+="\tAll the procedure dates should be different\n"
		 } 
		*/ 
		
	// Calculate Totals (if there are no errors)
	// Start, Kumar Gaurav,HPOV 299552,23/12/2008 
	if(isNaN(sForm.frmtotal.value))
	{
	bErr = true;
	//alert('Total should be number');
	sMsg = sMsg + "Total \t\t- Total should be number";
	}
   // End, Kumar Gaurav,HPOV 299552,23/12/2008
	if (!bErr) { 
		// calculate totals
		var sTemp = CalculateTotals('return')
		if (!isNull(sTemp)) {
			sMsg += sTemp;
			bErr = true;
		}
	}

	if (bErr) {   // There has been an error in the page somewhere... show the error
		alert(sMsg);
		if (bSubmit) { return false; } // if we are supposed to submit the form... do it.
		 // needs this - if its false then returning the value will force a page with 'true' on it
	} 
	
	if (bSubmit) { return true; } // if we are supposed to submit the form... do it.
}

function CalculateTotals(sType) {
	// sType - ('display' or 'return' -- alert the error or pass it back?
	var bCalcErr = false;
	var sCalcMsg = '';
	var sDefaultPaid = '0.00';
	var sFormPaid = sForm.frmpaid.value;
	var sFormDue = sForm.frmdue.value;
	var sFormTotal = sForm.frmtotal.value;

	var sComputeTotal;
	var sUseTotal;
	var sUsePaid;
	var sUseDue;
	
	var sP1Fee = sForm.frmtreat1fee.value;	
	var sP2Fee = sForm.frmtreat2fee.value;	
	var sP3Fee = sForm.frmtreat3fee.value;			
	
	var bTotalOK = true;
	var bPaidOK = true;
	var bDueOK = true;		
			
	// TOTALS
		// Total - computed
		sComputeTotal = 0; 

		 if (!isNaN(parseFloat(sP1Fee))) {  // Fee 1
		 	sComputeTotal = Math.abs(sComputeTotal + parseFloat(sP1Fee));
		 } 
		
		 if (!isNaN(parseFloat(sP2Fee))) {  // Fee 2
		 	sComputeTotal = Math.abs(sComputeTotal + parseFloat(sP2Fee));
		 } 
					 
		 if (!isNaN(parseFloat(sP3Fee))) {  // Fee 3
		 	sComputeTotal = Math.abs(sComputeTotal + parseFloat(sP3Fee));
		 } 
		 
			// Total must be less than £99,999.99 
			if (sComputeTotal > 99999.99) {
				bTotalOK = false;
				bCalcErr = true;	
				sCalcMsg += "\n - The invoice limit of £99,999.99 has been exceeded.";
			}
		 
			// deal with the form			
			sForm.frmtotal.value = RoundNumb(sComputeTotal); // done.
			parseFee(sForm.frmtotal);
			sUseTotal = sForm.frmtotal.value; // get the total back again
			
			// if these three fee's were all blank - sUseTotal looks like '0.00'
			if (sUseTotal == '0.00') {
				bTotalOK = false;
				bCalcErr = true;	
				sCalcMsg += "\n - Total is 0.00 - a valid total must be entered.";
			}

	// PAID
		// Paid - manually entered
		if (!isNull(sFormPaid)) { // validate it...
			if (!ExpressionChecker(sFormPaid,sValidFee)) {
				bCalcErr = true;				
				sCalcMsg += "\n - Paid amount is invalid.";
				bPaidOK = false;
			}  else {
				sUsePaid = sFormPaid;
			}
		} else { 
			sForm.frmpaid.value = sDefaultPaid; // see the sDefaultPaid setting above to determine how it looks.
			parseFee(sForm.frmpaid);			
			sUsePaid = sDefaultPaid;
		}	

	// DUE
		if (bPaidOK && bTotalOK) {
			// calculate the due amount
			sComputeDue = Math.abs(sUseTotal - sUsePaid);

				// deal with the form
				sForm.frmdue.value = RoundNumb(sComputeDue);
				parseFee(sForm.frmdue);
				sUseDue = sForm.frmdue.value; // get the value back again

			// check that paid is not more than due...				
			if (parseFloat(sUsePaid) > parseFloat(sUseTotal)) {
				bCalcErr = true;
				sCalcMsg += "\n - Amount paid must not be greater than the total.";	
				sForm.frmpaid.value = '';
				sForm.frmdue.value = '';							
			}				
		} else {
			bCalcErr = true;					
		}
		
	if (bCalcErr) {
		if (sType == 'display') {
			alert("Calculation Error: \n " + sCalcMsg)
		} else {
			return sCalcMsg;
		}
	}
}




function getKey(str){   
   if(isNull(str))
     return "";
     arrstr = str.split(g_cSeparator);
   return arrstr[0];
}								

function getValue(str){
    arrstr = str.split(g_cSeparator);
   return arrstr[1];
}
