Exemple #1
0
        protected override decimal GetPayAdjustment(TaxCode taxCode, PayPeriods periods /*, int period*/)
        {
            if (taxCode.IsNoAdjustmentCode || !taxCode.TaxCodeNumber.HasValue || taxCode.TaxCodeNumber.Value == 0)
            {
                return(0);
            }

            var codeNumber = taxCode.TaxCodeNumber.Value;
            var remainder  = ((codeNumber - 1m) % 500) + 1m;
            var quotient   = Math.Floor(codeNumber - remainder) / 500m;

            var payPeriodForQuotient = (periods == PayPeriods.Monthly ? PayPeriods.Monthly : PayPeriods.Weekly);
            var quotientMult         = TaxMath.UpRound(500 * (10 / (decimal)payPeriodForQuotient), 2);

            remainder = ((remainder * 10) + 9) / (int)payPeriodForQuotient;
            remainder = Math.Ceiling(remainder * 100) / 100;
            //remainder *= Math.Round((decimal)payPeriodForQuotient / (decimal)periods);
            quotient = quotient * quotientMult;

            var adjustment = (quotient + remainder);// * period;

            adjustment *= Math.Round((decimal)payPeriodForQuotient / (decimal)periods);

            if (taxCode.IsPrefixCode)
            {
                adjustment *= -1;
            }

            return(adjustment);
        }
Exemple #2
0
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            // The ST is back! But lower than PT.
            var niRates = TaxYearConfigurationData.NiRates[niCategory];

            // 'X' NI Code does not pay NI contributions
            if (niCategory == 'X')
            {
                gross = 0m;
            }

            var limitThresholds = GetLimitThresholdsForPeriods(payPeriods);

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, limitThresholds.LowerEarningsLimit, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, limitThresholds.PrimaryThreshold, limitThresholds.LowerEarningsLimit),
                EarningsAboveUEL = SubtractRound(gross, gross, limitThresholds.UpperEarningsLimit),
                EarningsAboveSTUpToIncludingPT  = SubtractRound(gross, limitThresholds.PrimaryThreshold, limitThresholds.SecondaryThreshold),
                EarningsAbovePTUptoIncludingUEL = SubtractRound(gross, limitThresholds.UpperEarningsLimit, limitThresholds.PrimaryThreshold),
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUpToIncludingPT * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAbovePTUptoIncludingUEL * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeE / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound((niCalc.EarningsAboveSTUpToIncludingPT + niCalc.EarningsAbovePTUptoIncludingUEL) * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErE / 100));

            return(niCalc);
        }
Exemple #3
0
        protected override void CreateContainer(TaxCode taxCode, decimal grossForPeriod, PayPeriods periods, int period = 1, bool week1 = false, decimal grossToDateExcludingPeriod = 0, decimal taxToDateExcludingPeriod = 0)
        {
            if (week1 || period == 1)
            {
                period = 1;
                grossToDateExcludingPeriod = 0;
                taxToDateExcludingPeriod   = 0;
            }

            CalculationContainer = new PayeCalculationContainer
            {
                TaxCode   = taxCode,
                Week1     = week1,
                Periods   = periods,
                TaxToDate = taxToDateExcludingPeriod,
                n         = period,
                pn        = grossForPeriod,
                Pn1       = grossToDateExcludingPeriod,
                Pn        = grossForPeriod + grossToDateExcludingPeriod,
                a1        = GetPayAdjustment(taxCode, periods),
                // Constants
                M = 50
            };

            CalculationContainer.na1 = CalculationContainer.a1 * CalculationContainer.n;
            CalculationContainer.Un  = CalculationContainer.Pn - CalculationContainer.na1;
            CalculationContainer.Tn  = TaxMath.Truncate(CalculationContainer.Un, 0);
        }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var niRates         = TaxYearConfigurationData.NiRates[niCategory];
            var limitThresholds = GetLimitThresholdsForPeriods(payPeriods);

#pragma warning disable IDE0017 // Simplify object initialization
            var niCalc = new NationalInsuranceCalculation();
#pragma warning restore IDE0017 // Simplify object initialization
            // Employee NI Gross
            niCalc.EmployeeNiGross  = TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.UpperAccrualPoint, limitThresholds.PrimaryThreshold) * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.UpperEarningsLimit, limitThresholds.UpperAccrualPoint) * (niRates.EeE / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, limitThresholds.UpperEarningsLimit) * (niRates.EeF / 100));

            niCalc.EmployeeNiRebate  = TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.SecondaryThreshold, limitThresholds.LowerEarningsLimit) * (niRates.EeB / 100));
            niCalc.EmployeeNiRebate += TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.PrimaryThreshold, limitThresholds.SecondaryThreshold) * (niRates.EeC / 100));

            // Employer NI Gross
            niCalc.EmployerNiGross  = TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.PrimaryThreshold, limitThresholds.SecondaryThreshold) * (niRates.ErC / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.UpperAccrualPoint, limitThresholds.PrimaryThreshold) * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.UpperEarningsLimit, limitThresholds.UpperAccrualPoint) * (niRates.ErE / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, limitThresholds.UpperEarningsLimit) * (niRates.ErF / 100));

            niCalc.EmployerNiRebate = TaxMath.HmrcRound(SubtractRound(gross, limitThresholds.SecondaryThreshold, limitThresholds.LowerEarningsLimit) * (niRates.ErB / 100));

            return(niCalc);
        }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var totalPT   = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.PrimaryThreshold);
            var totalST   = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.SecondaryThreshold);
            var totalUEL  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperEarningsLimit);
            var totalLEL  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.LowerEarningsLimit);
            var totalUST  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperSecondaryThreshold);
            var totalAUST = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.ApprenticeUpperSecondaryThreshold);

            var niRates = TaxYearSpecificProvider.GetCodeSpecifics(niCategory);

            var(periods, weeksInPeriod) = TaxMath.GetFactoring(payPeriods);
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodST  = TaxMath.PeriodRound(TaxMath.Factor(totalST, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = TaxMath.PeriodRound(TaxMath.Factor(totalUEL, weeksInPeriod, periods), weeksInPeriod),
                    periodLEL = Math.Ceiling(TaxMath.Factor(totalLEL, weeksInPeriod, periods));

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, periodLEL, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, periodPT, periodLEL),
                EarningsAbovePTUptoIncludingST  = SubtractRound(gross, periodST, periodPT),
                EarningsAboveSTUptoIncludingUEL = SubtractRound(gross, periodUEL, periodST),
                EarningsAboveUEL = SubtractRound(gross, gross, periodUEL)
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAbovePTUptoIncludingST * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeE / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErE / 100));

            return(niCalc);
        }
        protected virtual decimal SubtractRound(decimal gross, decimal limit, decimal subtract)
        {
            var subtractFrom = TaxMath.Smallest(gross, limit);
            var subtracted   = subtractFrom - subtract;

            subtracted = Math.Round(subtracted, 2, MidpointRounding.AwayFromZero);
            return(TaxMath.PositiveOnly(subtracted));
        }
        protected override void Calculateln()
        {
            CalculationContainer.ln = TaxMath.Truncate(CalculationContainer.Ln, 2);

            if (CalculationContainer.n > 1)
                CalculationContainer.ln -= CalculationContainer.TaxToDate;

            // In V13+ we always apply the regulatory limit
            CalculationContainer.ln = Math.Min(CalculationContainer.ln, TaxMath.Truncate(CalculationContainer.pn * (CalculationContainer.M / 100), 2));
        }
 public void BankersRoundingTest()
 {
     Assert.AreEqual(1m, TaxMath.BankersRound(0.99999m));
     Assert.AreEqual(1.96m, TaxMath.BankersRound(1.956m));
     Assert.AreEqual(2.96m, TaxMath.BankersRound(2.9555555m));
     Assert.AreEqual(2.47m, TaxMath.BankersRound(2.4719m));
     Assert.AreEqual(978.55m, TaxMath.BankersRound(978.54823m));
     Assert.AreEqual(8956.54m, TaxMath.BankersRound(8956.54168m));
     Assert.AreEqual(654.17m, TaxMath.BankersRound(654.168749m));
     Assert.AreEqual(236514.47m, TaxMath.BankersRound(236514.46984m));
     Assert.AreEqual(784.47m, TaxMath.BankersRound(784.4687m));
 }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var totalPT  = taxYearConfigurationData.PrimaryThreshold;
            var totalST  = taxYearConfigurationData.SecondaryThreshold;
            var totalUAP = taxYearConfigurationData.UpperAccrualPoint;
            var totalUEL = taxYearConfigurationData.UpperEarningsLimit;
            var totalLEL = taxYearConfigurationData.LowerEarningsLimit;
            var niRates  = taxYearConfigurationData.NiRates[niCategory];

            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodST  = TaxMath.PeriodRound(TaxMath.Factor(totalST, weeksInPeriod, periods), weeksInPeriod),
                    periodUAP = TaxMath.PeriodRound(TaxMath.Factor(totalUAP, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = TaxMath.PeriodRound(TaxMath.Factor(totalUEL, weeksInPeriod, periods), weeksInPeriod),
                    periodLEL = Math.Ceiling(TaxMath.Factor(totalLEL, weeksInPeriod, periods));

            var niCalc = new NationalInsuranceCalculation();

            // Employee NI Gross
            var lelToPt  = SubtractRound(gross, periodPT, periodLEL);
            var ptToSt   = SubtractRound(gross, periodST, periodPT);
            var stToUap  = SubtractRound(gross, periodUAP, periodST);
            var uapToUel = SubtractRound(gross, periodUEL, periodUAP);
            var aboveUel = SubtractRound(gross, gross, periodUEL);

            niCalc.EmployeeNiGross  = TaxMath.HmrcRound(ptToSt * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(stToUap * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(uapToUel * (niRates.EeE / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(aboveUel * (niRates.EeF / 100));

            niCalc.EmployeeNiRebate = TaxMath.HmrcRound(lelToPt * (niRates.EeB / 100));

            // Employer NI Gross
            //niCalc.EmployerNiGross = TaxMath.HmrcRound(ptToSt * (niRates.ErC / 100));
            if (!(niCategory == 'I' || niCategory == 'K' || niCategory == 'V'))
            {
                niCalc.EmployerNiGross += TaxMath.HmrcRound(stToUap * (niRates.ErD / 100));
            }
            niCalc.EmployerNiGross += TaxMath.HmrcRound(uapToUel * (niRates.ErE / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(aboveUel * (niRates.ErF / 100));

            niCalc.EmployerNiRebate  = TaxMath.HmrcRound(lelToPt * (niRates.ErB / 100));
            niCalc.EmployerNiRebate += TaxMath.HmrcRound(ptToSt * (niRates.ErC / 100));
            if ((niCategory == 'I' || niCategory == 'K' || niCategory == 'V'))
            {
                niCalc.EmployerNiRebate += TaxMath.HmrcRound(stToUap * (niRates.ErD / 100));
            }

            return(niCalc);
        }
        public StudentLoanCalculation CalculateStudentLoanDeduction(StudentLoanPlan plan, decimal gross, PayPeriods periods)
        {
            decimal threshold = 0, rate = 0, periodAdjustedThreshold, thresholdAdjustedGross, deduction;
            int     periodCnt     = 52;
            int     weeksInPeriod = 1;

            if (periods == PayPeriods.Monthly)
            {
                periodCnt = 12;
            }
            else
            {
                weeksInPeriod = (int)Math.Round((decimal)periodCnt / (int)periods);
            }

            switch (plan)
            {
            case StudentLoanPlan.Plan1:
                threshold = taxYearConfigurationData.Plan1StudentLoanThreshold;
                rate      = taxYearConfigurationData.Plan1StudentLoanRate;
                break;

            case StudentLoanPlan.Plan2:
                threshold = taxYearConfigurationData.Plan2StudentLoanThreshold;
                rate      = taxYearConfigurationData.Plan2StudentLoanRate;
                break;

            case StudentLoanPlan.Plan4:
                threshold = taxYearConfigurationData.Plan4StudentLoanThreshold;
                rate      = taxYearConfigurationData.Plan4StudentLoanRate;
                break;

            case StudentLoanPlan.PostGrad:
                threshold = taxYearConfigurationData.PostGradStudentLoanThreshold;
                rate      = taxYearConfigurationData.PostGradStudentLoanRate;
                break;
            }

            periodAdjustedThreshold = TaxMath.Truncate(((threshold * weeksInPeriod) / periodCnt), 2);
            thresholdAdjustedGross  = Math.Max(0, gross - periodAdjustedThreshold);
            deduction = Math.Floor(thresholdAdjustedGross * rate);

            return(new StudentLoanCalculation
            {
                Gross = gross,
                Threshold = threshold,
                Rate = rate,
                PeriodAdjustedThreshold = periodAdjustedThreshold,
                ThresholdAdjustedGross = thresholdAdjustedGross,
                StudentLoanDeduction = deduction
            });
        }
        protected override LimitThresholds CalculateLimitThresholdsForPeriods(PayPeriods payPeriods)
        {
            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;

            // WTF. UEL must round 865.3846 to 866. But PT must round 680.3333 to 680. This isn't sane.
            return(new LimitThresholds
            {
                PrimaryThreshold = TaxMath.PeriodRound(TaxMath.Factor(TaxYearConfigurationData.PrimaryThreshold, weeksInPeriod, periods), weeksInPeriod),
                UpperEarningsLimit = Math.Ceiling(TaxMath.Factor(TaxYearConfigurationData.UpperEarningsLimit, weeksInPeriod, periods)),
                LowerEarningsLimit = Math.Ceiling(TaxMath.Factor(TaxYearConfigurationData.LowerEarningsLimit, weeksInPeriod, periods)),
            });
        }
        protected override LimitThresholds CalculateLimitThresholdsForPeriods(PayPeriods payPeriods)
        {
            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;

            return(new LimitThresholds
            {
                PrimaryThreshold = TaxMath.PeriodRound(TaxMath.Factor(TaxYearConfigurationData.PrimaryThreshold, weeksInPeriod, periods), weeksInPeriod),
                SecondaryThreshold = TaxMath.PeriodRound(TaxMath.Factor(TaxYearConfigurationData.SecondaryThreshold, weeksInPeriod, periods), weeksInPeriod),
                UpperEarningsLimit = TaxMath.PeriodRound(TaxMath.Factor(TaxYearConfigurationData.UpperEarningsLimit, weeksInPeriod, periods), weeksInPeriod),
                LowerEarningsLimit = Math.Ceiling(TaxMath.Factor(TaxYearConfigurationData.LowerEarningsLimit, weeksInPeriod, periods)),
            });
        }
Exemple #13
0
        protected virtual void Calculateln()
        {
            CalculationContainer.ln = TaxMath.Truncate(CalculationContainer.Ln, 2);

            if (CalculationContainer.n > 1)
            {
                CalculationContainer.ln -= CalculationContainer.TaxToDate;
            }

            if (CalculationContainer.TaxCode.IsPrefixCode)
            {
                CalculationContainer.ln = Math.Min(CalculationContainer.ln, TaxMath.Truncate(CalculationContainer.pn * (CalculationContainer.M / 100), 2));
            }
        }
Exemple #14
0
        protected override LimitThresholds CalculateLimitThresholdsForPeriods(PayPeriods payPeriods)
        {
            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;

            // WTF. HMRC changed their rounding rules AGAIN in 2020. PeriodRound for the ST too.
            return(new LimitThresholds
            {
                PrimaryThreshold = TaxMath.PeriodRound(TaxMath.Factor(TaxYearConfigurationData.PrimaryThreshold, weeksInPeriod, periods), weeksInPeriod),
                SecondaryThreshold = TaxMath.PeriodRound(TaxMath.Factor(TaxYearConfigurationData.SecondaryThreshold, weeksInPeriod, periods), weeksInPeriod),
                UpperEarningsLimit = Math.Ceiling(TaxMath.Factor(TaxYearConfigurationData.UpperEarningsLimit, weeksInPeriod, periods)),
                LowerEarningsLimit = Math.Ceiling(TaxMath.Factor(TaxYearConfigurationData.LowerEarningsLimit, weeksInPeriod, periods)),
            });
        }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods periods)
        {
            int periodCnt     = 52;
            int weeksInPeriod = 1;

            if (periods == PayPeriods.Monthly)
            {
                periodCnt = 12;
            }
            else
            {
                weeksInPeriod = (int)Math.Round((decimal)periodCnt / (int)periods);
            }

            var totalPT  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.PrimaryThreshold);
            var totalST  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.SecondaryThreshold);
            var totalUAP = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperAccrualPoint);
            var totalUEL = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperEarningsLimit);
            var totalLEL = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.LowerEarningsLimit);
            var niRates  = TaxYearSpecificProvider.GetCodeSpecifics(niCategory);

            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periodCnt), weeksInPeriod),
                    periodST  = TaxMath.PeriodRound(TaxMath.Factor(totalST, weeksInPeriod, periodCnt), weeksInPeriod),
                    periodUAP = TaxMath.PeriodRound(TaxMath.Factor(totalUAP, weeksInPeriod, periodCnt), weeksInPeriod),
                    periodUEL = TaxMath.PeriodRound(TaxMath.Factor(totalUEL, weeksInPeriod, periodCnt), weeksInPeriod),
                    periodLEL = TaxMath.PeriodRound(TaxMath.Factor(totalLEL, weeksInPeriod, periodCnt), weeksInPeriod);

            var niCalc = new NationalInsuranceCalculation();

            // Employee NI Gross
            niCalc.EmployeeNiGross  = TaxMath.HmrcRound(SubtractRound(gross, periodUAP, periodPT) * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUEL, periodUAP) * (niRates.EeE / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, periodUEL) * (niRates.EeF / 100));

            niCalc.EmployeeNiRebate  = TaxMath.HmrcRound(SubtractRound(gross, periodST, periodLEL) * (niRates.EeB / 100));
            niCalc.EmployeeNiRebate += TaxMath.HmrcRound(SubtractRound(gross, periodPT, periodST) * (niRates.EeC / 100));

            // Employer NI Gross
            niCalc.EmployerNiGross  = TaxMath.HmrcRound(SubtractRound(gross, periodPT, periodST) * (niRates.ErC / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUAP, periodPT) * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUEL, periodUAP) * (niRates.ErE / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, periodUEL) * (niRates.ErF / 100));

            niCalc.EmployerNiRebate = TaxMath.HmrcRound(SubtractRound(gross, periodST, periodLEL) * (niRates.ErB / 100));

            return(niCalc);
        }
Exemple #16
0
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            // The ST is back! But lower than PT.
            var totalPT   = taxYearConfigurationData.PrimaryThreshold;
            var totalST   = taxYearConfigurationData.SecondaryThreshold;
            var totalUEL  = taxYearConfigurationData.UpperEarningsLimit;
            var totalLEL  = taxYearConfigurationData.LowerEarningsLimit;
            var totalUST  = taxYearConfigurationData.UpperSecondaryThreshold;
            var totalAUST = taxYearConfigurationData.ApprenticeUpperSecondaryThreshold;
            var niRates   = taxYearConfigurationData.NiRates[niCategory];

            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;

            // 'X' NI Code does not pay NI contributions
            if (niCategory == 'X')
            {
                gross = 0m;
            }

            // WTF. HMRC changed their rounding rules AGAIN in 2020. PeriodRound for the ST too.
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodST  = TaxMath.PeriodRound(TaxMath.Factor(totalST, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = Math.Ceiling(TaxMath.Factor(totalUEL, weeksInPeriod, periods)),
                    periodLEL = Math.Ceiling(TaxMath.Factor(totalLEL, weeksInPeriod, periods));

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, periodLEL, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, periodPT, periodLEL),
                EarningsAboveUEL = SubtractRound(gross, gross, periodUEL),
                EarningsAboveSTUpToIncludingPT  = SubtractRound(gross, periodPT, periodST),
                EarningsAbovePTUptoIncludingUEL = SubtractRound(gross, periodUEL, periodPT),
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUpToIncludingPT * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAbovePTUptoIncludingUEL * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeE / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound((niCalc.EarningsAboveSTUpToIncludingPT + niCalc.EarningsAbovePTUptoIncludingUEL) * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErE / 100));

            return(niCalc);
        }
        public void NumberTruncationTest()
        {
            Assert.AreEqual(9999.99999m, TaxMath.Truncate(9999.999999999m, 5));
            Assert.AreEqual(9999.9999m, TaxMath.Truncate(9999.999999999m, 4));
            Assert.AreEqual(9999.999m, TaxMath.Truncate(9999.999999999m, 3));
            Assert.AreEqual(9999.99m, TaxMath.Truncate(9999.999999999m, 2));
            Assert.AreEqual(9999.9m, TaxMath.Truncate(9999.999999999m, 1));
            Assert.AreEqual(9999m, TaxMath.Truncate(9999.999999999m, 0));
            Assert.AreEqual(9990m, TaxMath.Truncate(9999.999999999m, -1));

            Assert.AreEqual(-9999.99999m, TaxMath.Truncate(-9999.999999999m, 5));
            Assert.AreEqual(-9999.9999m, TaxMath.Truncate(-9999.999999999m, 4));
            Assert.AreEqual(-9999.999m, TaxMath.Truncate(-9999.999999999m, 3));
            Assert.AreEqual(-9999.99m, TaxMath.Truncate(-9999.999999999m, 2));
            Assert.AreEqual(-9999.9m, TaxMath.Truncate(-9999.999999999m, 1));
            Assert.AreEqual(-9999m, TaxMath.Truncate(-9999.999999999m, 0));
            Assert.AreEqual(-9990m, TaxMath.Truncate(-9999.999999999m, -1));
        }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods periods)
        {
            int periodCnt     = 52;
            int weeksInPeriod = 1;

            if (periods == PayPeriods.Monthly)
            {
                periodCnt = 12;
            }
            else
            {
                weeksInPeriod = (int)Math.Round((decimal)periodCnt / (int)periods);
            }

            var totalPT   = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.PrimaryThreshold);
            var totalST   = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.SecondaryThreshold);
            var totalUEL  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperEarningsLimit);
            var totalLEL  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.LowerEarningsLimit);
            var totalUST  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperSecondaryThreshold);
            var totalAUST = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.ApprenticeUpperSecondaryThreshold);

            var niRates = TaxYearSpecificProvider.GetCodeSpecifics(niCategory);

            // WTF. UEL must round 865.3846 to 866. But PT must round 680.3333 to 680. This isn't sane.
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periodCnt), weeksInPeriod),
                    periodUEL = Math.Ceiling(TaxMath.Factor(totalUEL, weeksInPeriod, periodCnt)),
                    periodLEL = Math.Ceiling(TaxMath.Factor(totalLEL, weeksInPeriod, periodCnt));

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, periodLEL, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, periodPT, periodLEL),
                EarningsAboveSTUptoIncludingUEL = SubtractRound(gross, periodUEL, periodPT),
                EarningsAboveUEL = SubtractRound(gross, gross, periodUEL)
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeD / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.ErC / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErD / 100));

            return(niCalc);
        }
Exemple #19
0
        protected override PayeInternalBracket[] GetBracketsForPeriod()
        {
            int  year = TaxYear, period = CalculationContainer.n, periods = (int)CalculationContainer.Periods;
            bool scottish = CalculationContainer.TaxCode.IsScotlandTax;

            Tuple <int, int, int, bool> brKey;

            if (BracketCache.ContainsKey(brKey = new Tuple <int, int, int, bool>(year, period, periods, scottish)))
            {
                return(BracketCache[brKey]);
            }

            var taxYearBrackets = GetBracketsFromProvider(TaxYear > 2016 ? scottish : false);
            var periodBrackets  = new List <PayeInternalBracket>();

            decimal lastC = 0, lastK = 0;

            foreach (var taxYearBracket in taxYearBrackets)
            {
#pragma warning disable IDE0017 // Simplify object initialization
                var periodBracket = new PayeInternalBracket();
#pragma warning restore IDE0017 // Simplify object initialization
                periodBracket.R = taxYearBracket.Multiplier;
                periodBracket.B = taxYearBracket.To - taxYearBracket.From;

                periodBracket.C = periodBracket.B + lastC;
                lastC           = periodBracket.C;

                periodBracket.c = TaxMath.Factor(periodBracket.C, period, periods);
                periodBracket.c = TaxMath.Truncate(periodBracket.c, 4);
                periodBracket.v = Math.Ceiling(periodBracket.c);

                periodBracket.K = lastK + TaxMath.Multiply(periodBracket.B, periodBracket.R, TaxMath.MultiplicationAccuracy.High);
                lastK           = periodBracket.K;

                periodBracket.k = TaxMath.Factor(periodBracket.K, period, periods);
                periodBracket.k = TaxMath.Truncate(periodBracket.k, 4);

                periodBrackets.Add(periodBracket);
            }

            BracketCache[brKey] = periodBrackets.ToArray();
            return(periodBrackets.ToArray());
        }
        public StudentLoanCalculationResult CalculateStudentLoanDeduction(StudentLoanPlan plan, decimal gross, PayPeriods periods)
        {
            decimal threshold = 0, rate = 0, periodAdjustedThreshold, thresholdAdjustedGross, deduction;
            int     periodCnt     = 52;
            int     weeksInPeriod = 1;

            if (periods == PayPeriods.Monthly)
            {
                periodCnt = 12;
            }
            else
            {
                weeksInPeriod = (int)Math.Round((decimal)periodCnt / (int)periods);
            }

            switch (plan)
            {
            case StudentLoanPlan.Plan1:
                threshold = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.Plan1StudentLoanThreshold);
                rate      = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.Plan1StudentLoanRate);
                break;

            case StudentLoanPlan.Plan2:
                threshold = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.Plan2StudentLoanThreshold);
                rate      = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.Plan2StudentLoanRate);
                break;
            }

            periodAdjustedThreshold = TaxMath.Truncate(((threshold * weeksInPeriod) / periodCnt), 2);
            thresholdAdjustedGross  = Math.Max(0, gross - periodAdjustedThreshold);
            deduction = Math.Floor(thresholdAdjustedGross * rate);

            return(new StudentLoanCalculationResult
            {
                Gross = gross,
                Threshold = threshold,
                Rate = rate,
                PeriodAdjustedThreshold = periodAdjustedThreshold,
                ThresholdAdjustedGross = thresholdAdjustedGross,
                StudentLoanDeduction = deduction
            });
        }
        /// <summary>
        /// Returns a rounded period value
        /// </summary>
        /// <param name="specificValueType"></param>
        /// <param name="period"></param>
        /// <returns></returns>
        public decimal GetPeriodTaxYearValue(TaxYearSpecificValues specificValueType, PayPeriods period)
        {
            // Get the annual value
            decimal annualValue = GetSpecificValue <decimal>(specificValueType);

            // By default for weekly we have 52 weeks in our period
            int periodCnt     = 52;
            int weeksInPeriod = 1;

            if (period == PayPeriods.Monthly)
            {
                periodCnt = 12;
            }
            else
            {
                weeksInPeriod = (int)Math.Round((decimal)periodCnt / (int)period);
            }

            return(TaxMath.PeriodRound((annualValue * weeksInPeriod) / periodCnt, weeksInPeriod));
        }
Exemple #22
0
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var totalPT   = taxYearConfigurationData.PrimaryThreshold;
            var totalST   = taxYearConfigurationData.SecondaryThreshold;
            var totalUEL  = taxYearConfigurationData.UpperEarningsLimit;
            var totalLEL  = taxYearConfigurationData.LowerEarningsLimit;
            var totalUST  = taxYearConfigurationData.UpperSecondaryThreshold;
            var totalAUST = taxYearConfigurationData.ApprenticeUpperSecondaryThreshold;
            var niRates   = taxYearConfigurationData.NiRates[niCategory];

            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;

            // 'X' NI Code does not pay NI contributions
            if (niCategory == 'X')
            {
                gross = 0m;
            }

            // WTF. UEL must round 865.3846 to 866. But PT must round 680.3333 to 680. This isn't sane.
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = Math.Ceiling(TaxMath.Factor(totalUEL, weeksInPeriod, periods)),
                    periodLEL = Math.Ceiling(TaxMath.Factor(totalLEL, weeksInPeriod, periods));

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, periodLEL, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, periodPT, periodLEL),
                EarningsAboveSTUptoIncludingUEL = SubtractRound(gross, periodUEL, periodPT),
                EarningsAboveUEL = SubtractRound(gross, gross, periodUEL)
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeD / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.ErC / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErD / 100));

            return(niCalc);
        }
Exemple #23
0
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var niRates = TaxYearConfigurationData.NiRates[niCategory];

            var niCalc          = new NationalInsuranceCalculation();
            var limitThresholds = GetLimitThresholdsForPeriods(payPeriods);

            // Employee NI Gross
            var lelToPt  = SubtractRound(gross, limitThresholds.PrimaryThreshold, limitThresholds.LowerEarningsLimit);
            var ptToSt   = SubtractRound(gross, limitThresholds.SecondaryThreshold, limitThresholds.PrimaryThreshold);
            var stToUap  = SubtractRound(gross, limitThresholds.UpperAccrualPoint, limitThresholds.SecondaryThreshold);
            var uapToUel = SubtractRound(gross, limitThresholds.UpperEarningsLimit, limitThresholds.UpperAccrualPoint);
            var aboveUel = SubtractRound(gross, gross, limitThresholds.UpperEarningsLimit);

            niCalc.EmployeeNiGross  = TaxMath.HmrcRound(ptToSt * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(stToUap * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(uapToUel * (niRates.EeE / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(aboveUel * (niRates.EeF / 100));

            niCalc.EmployeeNiRebate = TaxMath.HmrcRound(lelToPt * (niRates.EeB / 100));

            // Employer NI Gross
            //niCalc.EmployerNiGross = TaxMath.HmrcRound(ptToSt * (niRates.ErC / 100));
            if (!(niCategory == 'I' || niCategory == 'K' || niCategory == 'V'))
            {
                niCalc.EmployerNiGross += TaxMath.HmrcRound(stToUap * (niRates.ErD / 100));
            }
            niCalc.EmployerNiGross += TaxMath.HmrcRound(uapToUel * (niRates.ErE / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(aboveUel * (niRates.ErF / 100));

            niCalc.EmployerNiRebate  = TaxMath.HmrcRound(lelToPt * (niRates.ErB / 100));
            niCalc.EmployerNiRebate += TaxMath.HmrcRound(ptToSt * (niRates.ErC / 100));
            if ((niCategory == 'I' || niCategory == 'K' || niCategory == 'V'))
            {
                niCalc.EmployerNiRebate += TaxMath.HmrcRound(stToUap * (niRates.ErD / 100));
            }

            return(niCalc);
        }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var totalPT   = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.PrimaryThreshold);
            var totalST   = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.SecondaryThreshold);
            var totalUEL  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperEarningsLimit);
            var totalLEL  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.LowerEarningsLimit);
            var totalUST  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperSecondaryThreshold);
            var totalAUST = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.ApprenticeUpperSecondaryThreshold);

            var niRates = TaxYearSpecificProvider.GetCodeSpecifics(niCategory);

            // 'X' Ni Code does not pay NI contributions
            if (niCategory == 'X')
            {
                gross = 0m;
            }

            var(periods, weeksInPeriod) = TaxMath.GetFactoring(payPeriods);
            // WTF. UEL must round 865.3846 to 866. But PT must round 680.3333 to 680. This isn't sane.
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = Math.Ceiling(TaxMath.Factor(totalUEL, weeksInPeriod, periods)),
                    periodLEL = Math.Ceiling(TaxMath.Factor(totalLEL, weeksInPeriod, periods));

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, periodLEL, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, periodPT, periodLEL),
                EarningsAboveSTUptoIncludingUEL = SubtractRound(gross, periodUEL, periodPT),
                EarningsAboveUEL = SubtractRound(gross, gross, periodUEL)
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeD / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.ErC / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErD / 100));

            return(niCalc);
        }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var totalPT  = taxYearConfigurationData.PrimaryThreshold;
            var totalST  = taxYearConfigurationData.SecondaryThreshold;
            var totalUAP = taxYearConfigurationData.UpperAccrualPoint;
            var totalUEL = taxYearConfigurationData.UpperEarningsLimit;
            var totalLEL = taxYearConfigurationData.LowerEarningsLimit;
            var niRates  = taxYearConfigurationData.NiRates[niCategory];

            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodST  = TaxMath.PeriodRound(TaxMath.Factor(totalST, weeksInPeriod, periods), weeksInPeriod),
                    periodUAP = TaxMath.PeriodRound(TaxMath.Factor(totalUAP, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = TaxMath.PeriodRound(TaxMath.Factor(totalUEL, weeksInPeriod, periods), weeksInPeriod),
                    periodLEL = TaxMath.PeriodRound(TaxMath.Factor(totalLEL, weeksInPeriod, periods), weeksInPeriod);

#pragma warning disable IDE0017 // Simplify object initialization
            var niCalc = new NationalInsuranceCalculation();
#pragma warning restore IDE0017 // Simplify object initialization
            // Employee NI Gross
            niCalc.EmployeeNiGross  = TaxMath.HmrcRound(SubtractRound(gross, periodUAP, periodPT) * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUEL, periodUAP) * (niRates.EeE / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, periodUEL) * (niRates.EeF / 100));

            niCalc.EmployeeNiRebate  = TaxMath.HmrcRound(SubtractRound(gross, periodST, periodLEL) * (niRates.EeB / 100));
            niCalc.EmployeeNiRebate += TaxMath.HmrcRound(SubtractRound(gross, periodPT, periodST) * (niRates.EeC / 100));

            // Employer NI Gross
            niCalc.EmployerNiGross  = TaxMath.HmrcRound(SubtractRound(gross, periodPT, periodST) * (niRates.ErC / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUAP, periodPT) * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUEL, periodUAP) * (niRates.ErE / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, periodUEL) * (niRates.ErF / 100));

            niCalc.EmployerNiRebate = TaxMath.HmrcRound(SubtractRound(gross, periodST, periodLEL) * (niRates.ErB / 100));

            return(niCalc);
        }
Exemple #26
0
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var totalPT  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.PrimaryThreshold);
            var totalST  = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.SecondaryThreshold);
            var totalUAP = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperAccrualPoint);
            var totalUEL = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.UpperEarningsLimit);
            var totalLEL = TaxYearSpecificProvider.GetSpecificValue <decimal>(TaxYearSpecificValues.LowerEarningsLimit);
            var niRates  = TaxYearSpecificProvider.GetCodeSpecifics(niCategory);

            var(periods, weeksInPeriod) = TaxMath.GetFactoring(payPeriods);
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodST  = TaxMath.PeriodRound(TaxMath.Factor(totalST, weeksInPeriod, periods), weeksInPeriod),
                    periodUAP = TaxMath.PeriodRound(TaxMath.Factor(totalUAP, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = TaxMath.PeriodRound(TaxMath.Factor(totalUEL, weeksInPeriod, periods), weeksInPeriod),
                    periodLEL = TaxMath.PeriodRound(TaxMath.Factor(totalLEL, weeksInPeriod, periods), weeksInPeriod);

#pragma warning disable IDE0017 // Simplify object initialization
            var niCalc = new NationalInsuranceCalculation();
#pragma warning restore IDE0017 // Simplify object initialization
                                // Employee NI Gross
            niCalc.EmployeeNiGross  = TaxMath.HmrcRound(SubtractRound(gross, periodUAP, periodPT) * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUEL, periodUAP) * (niRates.EeE / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, periodUEL) * (niRates.EeF / 100));

            niCalc.EmployeeNiRebate  = TaxMath.HmrcRound(SubtractRound(gross, periodST, periodLEL) * (niRates.EeB / 100));
            niCalc.EmployeeNiRebate += TaxMath.HmrcRound(SubtractRound(gross, periodPT, periodST) * (niRates.EeC / 100));

            // Employer NI Gross
            niCalc.EmployerNiGross  = TaxMath.HmrcRound(SubtractRound(gross, periodPT, periodST) * (niRates.ErC / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUAP, periodPT) * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, periodUEL, periodUAP) * (niRates.ErE / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(SubtractRound(gross, gross, periodUEL) * (niRates.ErF / 100));

            niCalc.EmployerNiRebate = TaxMath.HmrcRound(SubtractRound(gross, periodST, periodLEL) * (niRates.ErB / 100));

            return(niCalc);
        }
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var niRates = TaxYearConfigurationData.NiRates[niCategory];

            var limitThresholds = GetLimitThresholdsForPeriods(payPeriods);

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, limitThresholds.LowerEarningsLimit, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, limitThresholds.PrimaryThreshold, limitThresholds.LowerEarningsLimit),
                EarningsAbovePTUptoIncludingST  = SubtractRound(gross, limitThresholds.SecondaryThreshold, limitThresholds.PrimaryThreshold),
                EarningsAboveSTUptoIncludingUEL = SubtractRound(gross, limitThresholds.UpperEarningsLimit, limitThresholds.SecondaryThreshold),
                EarningsAboveUEL = SubtractRound(gross, gross, limitThresholds.UpperEarningsLimit)
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAbovePTUptoIncludingST * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeE / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErE / 100));

            return(niCalc);
        }
Exemple #28
0
        public override NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods)
        {
            var totalPT   = taxYearConfigurationData.PrimaryThreshold;
            var totalST   = taxYearConfigurationData.SecondaryThreshold;
            var totalUEL  = taxYearConfigurationData.UpperEarningsLimit;
            var totalLEL  = taxYearConfigurationData.LowerEarningsLimit;
            var totalUST  = taxYearConfigurationData.UpperSecondaryThreshold;
            var totalAUST = taxYearConfigurationData.ApprenticeUpperSecondaryThreshold;
            var niRates   = taxYearConfigurationData.NiRates[niCategory];

            var factoring     = TaxMath.GetFactoring(payPeriods);
            int periods       = factoring.Periods,
                weeksInPeriod = factoring.WeeksInPeriod;
            decimal periodPT  = TaxMath.PeriodRound(TaxMath.Factor(totalPT, weeksInPeriod, periods), weeksInPeriod),
                    periodST  = TaxMath.PeriodRound(TaxMath.Factor(totalST, weeksInPeriod, periods), weeksInPeriod),
                    periodUEL = TaxMath.PeriodRound(TaxMath.Factor(totalUEL, weeksInPeriod, periods), weeksInPeriod),
                    periodLEL = Math.Ceiling(TaxMath.Factor(totalLEL, weeksInPeriod, periods));

            var niCalc = new NationalInsuranceCalculation
            {
                EarningsUptoIncludingLEL        = SubtractRound(gross, periodLEL, 0),
                EarningsAboveLELUptoIncludingPT = SubtractRound(gross, periodPT, periodLEL),
                EarningsAbovePTUptoIncludingST  = SubtractRound(gross, periodST, periodPT),
                EarningsAboveSTUptoIncludingUEL = SubtractRound(gross, periodUEL, periodST),
                EarningsAboveUEL = SubtractRound(gross, gross, periodUEL)
            };

            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAbovePTUptoIncludingST * (niRates.EeC / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.EeD / 100));
            niCalc.EmployeeNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.EeE / 100));

            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveSTUptoIncludingUEL * (niRates.ErD / 100));
            niCalc.EmployerNiGross += TaxMath.HmrcRound(niCalc.EarningsAboveUEL * (niRates.ErE / 100));

            return(niCalc);
        }