예제 #1
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);
        }
예제 #2
0
        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 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
            });
        }
예제 #4
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));
            }
        }
예제 #5
0
        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));
        }
예제 #6
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());
        }
예제 #7
0
        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
            });
        }