FallenPaladin 0 Junior Poster in Training

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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.