/*
Contractor Calculator v1.4
Created by James Llewellyn - Oriel Holdings Ltd 2009
*/

// default variables
var minpayrate = 7.5 // £
var taxcode = 6475;
var holidayallowance = 12.07; // %
var minrate = 5.8;
var milerate = 0.4;
var annualweeks = 52;
var adminfee = 15; // £
var employersni = 12.8; // %
var primarythreshold = 110;
var incometaxthresholdvalue = 37400;
var class1 = 11; // %
var upperlimit = 844;
var upperearnings = 1; // %
var soletraderfee = 25; // £
var vat = 15; // %
var dp = 12;
var payetax = 20; // %

// input variables
var hours;
var payrate;
var expenses;
var miles;
var subsistence;

// calculated variables
var weeklyallowance;
var grosspay;
var totalexpenses;
var mingrosspay;
var minholiday;
var minpayment;
var maxexpensesclaim;
var expensesclaimed;
var expensescfwd;
var minratetax;
var paye_netpay;
var umbrella_netpay;
var umbrella_weeklybenefit;
var umbrella_annualbenefit;
var umbrella_incomeretained;
var umbrella_holidaypay;
var umbrella_taxfee;
var soletrader_netpay;
var soletrader_netpay;
var soletrader_weeklybenefit;
var soletrader_annualbenefit;
var soletrader_incomeretained;
var cis_netpay;
var cis_weeklybenefit;
var cis_annualbenefit;
var cis_incomeretained;

// functions
function GetFormValues() {

	// hours worked
	with (document.getElementById("txtHours")) {
		if (value.length > 0) {
			hours = parseFloat(value);
		}
		else {
			hours = 0;
		}
	}
	
	// pay rate per hour
	with (document.getElementById("txtPayRate")) {
		if (value.length > 0) {
			payrate = parseFloat(value);	
		}
		else {
			payrate = 0;	
		}
	}
	
	// expenses per week
	with (document.getElementById("txtExpenses")) {
		if (value.length > 0) {
			expenses = parseFloat(value);
		}
		else {
			expenses = 0;
		}
	}
	
	// mileage
	with (document.getElementById("txtMiles")) {
		if (value.length > 0) {
			miles = parseFloat(value);	
		}
		else {
			miles = 0;
		}
	}
	
	// subsistence
	with (document.getElementById("txtSubsistence")) {
		if (value.length > 0) {
			subsistence = parseFloat(value);	
		}
		else {
			subsistence = 0;	
		}
	}
}

function LessThanEqualToZero(i) {
	if (i <= 0) {
		return 0;
	}
	else {
		return i;
	}
}

function HideOutput() {
	document.getElementById("output").style.display = "none";
}

function IncomeTax(i) {
	
	var j;
	
	if (i < minratetax) {
		// lower rate threshold
		j = (i * (20 / 100));
	}
	else {
		// higher rate threshold
		j = ((minratetax * (20 / 100)) + ((i - minratetax) * (40 / 100)));
	}
	
	return parseFloat((j).toFixed(dp));
}

function NationalInsurance(p) {

	var ni;

	if (LessThanEqualToZero(p - primarythreshold) != 0) {
		if (p < upperlimit) {
			ni = ((p - primarythreshold) * (class1 / 100));
		}
		else {
			ni = ((upperlimit * (class1 / 100)) + ((p - upperlimit) * (upperearnings / 100)));
		}
	}
	else {
		ni = 0;
	}
	
	return parseFloat((ni).toFixed(dp));
}

function PAYE() {
	
	var p_grosspay;
	var p_taxpay;
	var p_incometax;
	var p_nationalinsurance;
	var p_netpay;
	
	// gross pay (minus employers ni)
	p_grosspay = parseFloat((grosspay * (1 / ((parseInt(employersni.toFixed()) / 100) + 1))).toFixed(dp))
	
	// taxable pay
	p_taxpay = parseFloat((LessThanEqualToZero(p_grosspay - weeklyallowance)).toFixed(dp));
	
	// income tax
	p_incometax = IncomeTax(p_taxpay);
	
	// national insurance
	p_nationalinsurance = NationalInsurance(p_grosspay);
	
	// net pay
	paye_netpay = parseFloat((p_grosspay - p_incometax - p_nationalinsurance).toFixed(dp));
}

function SoleTrader() {

	// requires paye calculation
	
	// net pay
	soletrader_netpay = parseFloat((grosspay - (soletraderfee * (vat / 100) + soletraderfee)).toFixed(dp));
	
	// weekly benefit
	soletrader_weeklybenefit = parseFloat((soletrader_netpay - paye_netpay).toFixed(dp));
	
	// annual benefit
	soletrader_annualbenefit = parseFloat((soletrader_weeklybenefit * annualweeks).toFixed(dp));
	
	// percentage retained
	soletrader_incomeretained = ((soletrader_netpay / grosspay) * 100).toFixed(2);
}

function CIS() {

	// requires paye calculation

	// net pay
	cis_netpay = parseFloat(((grosspay - adminfee) * (80 / 100)).toFixed(dp));
	
	// weekly benefit
	cis_weeklybenefit = parseFloat((cis_netpay - paye_netpay).toFixed(dp));
	
	// annual benefit
	cis_annualbenefit = parseFloat((cis_weeklybenefit * annualweeks).toFixed(dp));
	
	// percentage retained
	cis_incomeretained = ((cis_netpay / grosspay) * 100).toFixed(2);
}

function Umbrella() {

	// requires paye calculation

	var u_allowableexpenses;
	var u_grosspay;
	var u_employersni;
	var u_pay;
	var u_taxpay;
	var u_incometax;
	var u_nationalinsurance;
	var u_weeklybenefit;
	var u_annualbenefit;
	var u_incomeretained;
	var u_holidaypay;
	
	// allowable expenses
	if (expensesclaimed > totalexpenses) {
		u_allowableexpenses = totalexpenses;
	}
	else {
		u_allowableexpenses = expensesclaimed;
	}
	
	// gross pay
	u_grosspay = parseFloat((grosspay - u_allowableexpenses - adminfee).toFixed(dp));
	
	// employers ni
	u_employersni = parseFloat(((u_grosspay - primarythreshold) * ((employersni / 100) / (1 + (employersni / 100)))).toFixed(dp));
	
	// pay
	u_pay = parseFloat((u_grosspay - u_employersni).toFixed(dp));
	
	// taxable pay
	u_taxpay = parseFloat((LessThanEqualToZero(u_pay - weeklyallowance)).toFixed(dp));
	
	// income tax
	u_incometax = IncomeTax(u_taxpay);

	// national insurance
	u_nationalinsurance = NationalInsurance(u_pay);
	
	// net pay
	umbrella_netpay = parseFloat((u_pay - u_incometax - u_nationalinsurance + u_allowableexpenses).toFixed(dp)); // assign value to global var
	
	// weekly benefit
	umbrella_weeklybenefit = parseFloat((umbrella_netpay - paye_netpay).toFixed(dp));
	
	// annual benefit
	umbrella_annualbenefit = parseFloat((umbrella_weeklybenefit * annualweeks).toFixed(dp));

	// percentage retained
	umbrella_incomeretained = ((umbrella_netpay / grosspay) * 100).toFixed(2);

	// holiday pay
	umbrella_holidaypay = parseFloat(((hours * minrate * holidayallowance) / 100).toFixed(dp));
	
	// admin fee after tax
	umbrella_taxfee = parseFloat((adminfee - (((adminfee / 100) * employersni) + ((adminfee / 100) * class1) + ((adminfee / 100) * payetax))));
}

function Output() {
	
	var u = "umbrella";
	var c = "cis";
	var s = "soletrader";
	
	var wb = "weeklybenefit";
	var ab = "annualbenefit";
	var ir = "incomeretained";
	var np = "netpay";
	
	var sSeparator = "_";
	var sCurrency = "&pound;";
	var sPercent = "%";
	
	with (document.getElementById("results")) {
		
		for (row = 0; row < rows.length; row++)
		{
			switch (rows[row].id)
			{
				case wb: case ab: case ir: case np:
					
					for (cell = 0; cell < rows[row].cells.length; cell++)
					{
						switch (rows[row].id)
						{
							case ir:
							
								switch (rows[row].cells[cell].id)
								{
									case u: case c: case s:
									
										rows[row].cells[cell].innerHTML = eval(rows[row].cells[cell].id + sSeparator + ir) + sPercent;
										
										break;
								}
							
								break;
								
							default:
							
								switch (rows[row].cells[cell].id)
								{
									case u: case c: case s:
							
										rows[row].cells[cell].innerHTML = sCurrency + eval(rows[row].cells[cell].id + sSeparator + rows[row].id).toFixed(2);
								
										break;
								}
								
								break;
						}
					}
					
					break;
			}
		}
	}
	
	
	with (document)
	{
		// Set dynamic text
		getElementById("d1").innerHTML = "We estimate that with Oriel's Umbrella Solution you will save <strong>" + sCurrency + eval(u + sSeparator + wb).toFixed(2) + "</strong> per week.<br />That is <strong>" + sCurrency + eval(u + sSeparator + ab).toFixed(2) + "</strong> per annum.";
		
		if (expensescfwd > 0)
		{
			getElementById("d1").innerHTML = getElementById("d1").innerHTML + " Expenses carried forwards: " + sCurrency + expensescfwd.toFixed(2);
		}
	
		getElementById("d2").innerHTML = "The Oriel Umbrella Weekly Income figure includes holiday pay of " + sCurrency + eval(u + sSeparator + "holidaypay").toFixed(2);
		
		getElementById("d3").innerHTML = "The PAYE weekly income figures assume the agency pays a lower rate per hour to PAYE workers due to the cost to the agency of Employers NI. PAYE net pay comparison is " + sCurrency + paye_netpay.toFixed(2);
		
		getElementById("d4").innerHTML = "Oriel's Umbrella Solution has a low fixed fee of <strong>" + sCurrency + adminfee + " per week</strong> (" + sCurrency + umbrella_taxfee.toFixed(2) + " after basic rate tax) giving you more take home pay than our market leading competitors";
		
		// Display output div
		getElementById("output").style.display = "inline";
	}
}

function Calculate() {
	
	// retrieve form values
	GetFormValues();
	
	// check required inputs
	if (hours > 0 && payrate > 0) {
		
		if (payrate >= minpayrate) {
		
			// set global calculated variables
			weeklyallowance = parseFloat((taxcode / annualweeks).toFixed(dp));
			grosspay = parseFloat((hours * payrate).toFixed(dp));
			totalexpenses = parseFloat((expenses + subsistence + (miles * milerate)).toFixed(dp));
			mingrosspay = parseFloat((minrate * hours).toFixed(dp));
			minholiday = parseFloat((mingrosspay * (holidayallowance / 100)).toFixed(dp));
			minpayment = parseFloat((mingrosspay + minholiday).toFixed(dp));
			expensesclaimed = parseFloat(LessThanEqualToZero(grosspay - minpayment - adminfee - (minpayment - primarythreshold) * (employersni / 100)).toFixed(dp));
			expensescfwd = parseFloat(LessThanEqualToZero(totalexpenses - expensesclaimed).toFixed(dp));
			minratetax = parseFloat((incometaxthresholdvalue / annualweeks).toFixed(dp));
			
			// execute individual calculations
			PAYE();
			CIS();
			SoleTrader();
			Umbrella();
			
			if (paye_netpay > 0) {
			
				// output calculated values
				Output();
			}
			else {
				
				HideOutput();
				
				alert("Please contact us as based on the information you have entered the Oriel Umbrella is not currently beneficial to you.");
			}
			
		}
		else {
			
			HideOutput();
			
			alert("Your pay rate must equal or exceed " + minpayrate.toFixed(2) + " for Oriel Umbrella to be of benefit to you.\n\nPlease contact us as we still may be able to help.");
		}
	}
	else {
		
		HideOutput();
		
		alert("Please fill in all mandatory (*) fields");
	}
}
