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); }
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 }); }
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)); } }
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)); }
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 }); }