Hi I am currently writing a PAYE system for a HND project, some of you reading this may have already helped with some of the questions I have posted, and I thank you for the help. However, I have stumbled upon an error that I can not understand.
I suppose it would be defined as a logic error, but not sure if this is quite correct.
The Problem:
A child form has a combo box, populated by a linq expression, the value of the text is then used to filter a binding source. When the binding source has been filtered, non bound data columns are populated programtically with calculated values. This works perfectly well untill the final 2 columns were added. The addition of the final 2 column calculations has caused the data grid view to function strangly.....not all fields held by the binding source are returned as the week number column is being rewritten.
Selection code:
private void tsCmbWeek_SelectedIndexChanged(object sender, EventArgs e)
{
if ((tsCmbWeek.Text == "No Filter") || (tsCmbWeek.Text == ""))
{
vwContractP11BindingSource.Filter = "";
vwContractP11DataGridView.Visible = true;
if (tsCmbWeek.Text == "")
{
vwContractP11DataGridView.Visible = false;
}
}
else
{
vwContractP11BindingSource.Filter = "Week_Number = " + tsCmbWeek.Text;
vwContractP11DataGridView.Visible = true;
decimal wage = 0;
char tableLetter = 'A';
NI_Calculations calcNI = null;
for(int rowNum = 0; rowNum < vwContractP11DataGridView.RowCount; rowNum++)
{
//Set arguments
wage = ((decimal)vwContractP11DataGridView.Rows[rowNum].Cells["dgvPay"].Value);
tableLetter = (vwContractP11DataGridView.Rows[rowNum].Cells["dgvTable"].Value.ToString()[0]);
//Calc NI
calcNI = new NI_Calculations(tableLetter, wage);
//Populate the datagridview
vwContractP11DataGridView.Rows[rowNum].Cells["dgvCol1A"].Value = calcNI.col1A;
vwContractP11DataGridView.Rows[rowNum].Cells["dgvCol1B"].Value = calcNI.col1B;
vwContractP11DataGridView.Rows[rowNum].Cells["dgvCol1C"].Value = calcNI.col1C;
vwContractP11DataGridView.Rows[rowNum].Cells["dgvCol1D"].Value = calcNI.col1D;
vwContractP11DataGridView.Rows[rowNum].Cells["dgvCol1E"].Value = calcNI.colOverUEL;
vwContractP11DataGridView.Rows[rowNum].Cells["dgvColEmp"].Value = calcNI.employeesNICs;
vwContractP11DataGridView.Rows[rowNum].Cells["dgvColBoss"].Value = calcNI.employersNICs;
}
}
}
The following is the code for the NI_Calculations class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PAyRollApplication_V2
{
class NI_Calculations
{
//National Insurance band information
protected decimal GP = 0;//Gross pay for NI purposes
protected decimal LEL = 0;//Lower earnings limit
protected decimal UAP = 0;//Upper Accrual point
protected decimal UEL = 0;//Upper earnings limit
protected decimal ET = 0;//Earnings threashold
//Employee band percetage information
protected decimal empBandA = 0;
protected decimal empBandB = 0;
protected decimal empBandC = 0;
protected decimal empBandD = 0;
protected decimal empBandE = 0;
//Employers band percent information
protected decimal bossBandA = 0;
protected decimal bossBandB = 0;
protected decimal bossBandC = 0;
protected decimal bossBandD = 0;
protected decimal bossBandE = 0;
private decimal _employeesNICs = 0;//Nation insurance contributions
private decimal _employersNICs = 0;//Employers NI contributions
//P11 column variables
private decimal _col1A = 0;
private decimal _col1B = 0;
private decimal _col1C = 0;
private decimal _col1D = 0;
private decimal _colOverUEL = 0;
//Pay period constant = one week
protected int P = 1;
//Weekly devisor = number of weeks in the year
protected int w = 52;
LinqLoginDataContext dc = new LinqLoginDataContext();//Linq connectivity requirment
//Constructor logic
public NI_Calculations(char NI_Table, decimal grossPay)
{
GP = grossPay;
try
{
//try to load in the values as required
var constant = from aCon in dc.tblNI_Constants
select new
{
aCon.Band,
aCon.Value
};
//Populate variables with values
foreach (var aCon in constant)
{
switch (aCon.Band)
{
case ("ET"):
ET = (decimal)aCon.Value;
break;
case ("LEL"):
LEL = (decimal)aCon.Value;
break;
case ("UAP"):
UAP = (decimal)aCon.Value;
break;
case ("UEL"):
UEL = (decimal)aCon.Value;
break;
}
}
var employeeBands = from niTables in dc.tblNI_tables
where niTables.Table_Letter == NI_Table
select new
{
niTables.Band_A,
niTables.Band_B,
niTables.Band_C,
niTables.Band_D,
niTables.Band_E
};
//Populate variables with values
foreach (var band in employeeBands)
{
empBandA = band.Band_A / 100;
empBandB = band.Band_B / 100;
empBandC = band.Band_C / 100;
empBandD = band.Band_D / 100;
empBandE = band.Band_E / 100;
}
var employerBands = from niTables in dc.tblEmployer_NI_Tables
where niTables.Table_Letter == NI_Table
select new
{
niTables.Band_A,
niTables.Band_B,
niTables.Band_C,
niTables.Band_D,
niTables.Band_E
};
//Populate variables with values
foreach (var band in employerBands)
{
bossBandA = band.Band_A / 100;
bossBandB = band.Band_B / 100;
bossBandC = band.Band_C / 100;
bossBandD = band.Band_D / 100;
bossBandE = band.Band_E / 100;
}
}
catch(Exception ex)
{
throw new Exception("Error accessing NI constants: ERROR CODE 101\n" + ex.ToString());
}
CalcEmployeesNIDue();
CalcEmployersNI();
}
#region Read only members
public decimal col1A
{
get
{
return _col1A;
}
}
public decimal col1B
{
get
{
return _col1B;
}
}
public decimal col1C
{
get
{
return _col1C;
}
}
public decimal col1D
{
get
{
return _col1D;
}
}
public decimal colOverUEL
{
get
{
return _colOverUEL;
}
}
public decimal employeesNICs
{
get
{
return _employeesNICs;
}
}
public decimal employersNICs
{
get
{
return _employersNICs;
}
}
public decimal totalNICs
{
get
{
return (_employeesNICs + _employersNICs);
}
}
#endregion
private void CalcEmployeesNIDue()
{
//Calc earnings that are due for tax
//Step 1: Earnings up to and including LEL
_col1A = CalcBand(LEL);
if (_col1A > 0)
{
//Step 2: Earnings above LEL up to and including ET
_col1B = _col1A - CalcBand(ET);
//step 3: Earnings above ET up to and including UAP
_col1C = (CalcBand(ET) - CalcBand(UAP));
//step 4: Earnings above UAP up to and including UEL
_col1D = (CalcBand(UAP) - CalcBand(UEL));
//step 5: Earnings above UEL
_colOverUEL = CalcBand(UEL);
//Calc tax due
//step 6: multiple step 3 by employee's band C % (round) +
//step 4 by employee's band D % (round) +
//step 5 by employee's band E % (round)
_employeesNICs = (Math.Round((_col1C * empBandC) - 0.005M, 2, MidpointRounding.AwayFromZero) + Math.Round((_col1D * empBandD) - 0.005M, 2, MidpointRounding.AwayFromZero) + Math.Round((_colOverUEL * empBandE) - 0.005M, 2, MidpointRounding.AwayFromZero));
//Minus the rebate
//Rebate = step 2 * band B (round)
_employeesNICs = _employeesNICs - (Math.Round((_col1B * empBandB) - 0.005M, 2, MidpointRounding.AwayFromZero));
}
}
private void CalcEmployersNI()
{
//Method to calculate the employers NI contribution
//Should not be run before CalcEmployeesNIDue()
//Step 3: multiplied by employers band C
_employersNICs = (Math.Round((_col1C * bossBandC) - 0.005M, 2, MidpointRounding.AwayFromZero) + Math.Round((_col1D * bossBandD) - 0.005M, 2, MidpointRounding.AwayFromZero) + Math.Round((_colOverUEL * bossBandE) - 0.005M, 2, MidpointRounding.AwayFromZero));
//Minus the rebate
if (_employeesNICs < 0)
{
//Any remaining rebat from the employees net NICs payment
_employersNICs = _employersNICs - (Math.Round((_col1B * bossBandB) - 0.005M, 2, MidpointRounding.AwayFromZero) + _employeesNICs);
}
else
{
_employersNICs = _employersNICs - (Math.Round((_col1B * bossBandB) - 0.005M, 2, MidpointRounding.AwayFromZero));
}
}
private decimal CalcBand(decimal band)
{
//Method to calculate Column 1A of P11 form
decimal upToLEL = (GP - ((band * P) / w));
if ((upToLEL < 0)&&(band != LEL))
{
upToLEL = 0;
}
return Math.Round(upToLEL - 0.005M,0, MidpointRounding.AwayFromZero);
}
}
}
any help would be greatly received thanks.