/// <summary>Returns existing payperiod if it exists, otherwise inserts and returns a new payperiod. Throws exception if payperiod overlaps existing payperiod.</summary> public static PayPeriod CreateTwoWeekPayPeriodIfNotExists(DateTime start) { PayPeriod ppNew = new PayPeriod(); ppNew.DateStart = start; ppNew.DateStop = start.AddDays(13); ppNew.DatePaycheck = start.AddDays(16); //check for identical or overlapping pay periods PayPeriods.RefreshCache(); foreach (PayPeriod ppInDb in PayPeriods.GetDeepCopy()) { if (ppInDb.DateStart == ppNew.DateStart && ppInDb.DateStop == ppNew.DateStop && ppInDb.DatePaycheck == ppNew.DatePaycheck) { //identical pay period already exists. return(ppInDb); } //if(pp.DateStart == payP.DateStart && pp.DateStop == payP.DateStop && pp.DatePaycheck != payP.DatePaycheck) { // //identical pay period already exists, just with a different pay check date. // //This is a seperate check because it may be important in the future. // continue; //} if (ppInDb.DateStop > ppNew.DateStart && ppInDb.DateStart < ppNew.DateStop) { //pay periods overlap throw new Exception("Error inserting pay period. New Pay period overlaps existing pay period.\r\n"); } } PayPeriods.Insert(ppNew); return(ppNew); }
public void TimeCardRules_CalculateWeeklyOvertime_OneWeekOverTwoPayPeriods() { string suffix = "26"; DateTime startDate = DateTime.Parse("2001-02-01"); //This will create a pay period that splits a work week. Employee emp = EmployeeT.CreateEmployee(suffix); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriod payP2 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate.AddDays(14)); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 0); TimeCardRules.RefreshCache(); long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(10).AddHours(6), startDate.AddDays(10).AddHours(17), 0); long clockEvent2 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(11).AddHours(6), startDate.AddDays(11).AddHours(17), 0); long clockEvent3 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(12).AddHours(6), startDate.AddDays(12).AddHours(17), 0); //new pay period long clockEvent4 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(14).AddHours(6), startDate.AddDays(14).AddHours(17), 0); TimeCardRules.CalculateWeeklyOvertime(emp, payP1.DateStart, payP1.DateStop); TimeCardRules.CalculateWeeklyOvertime(emp, payP2.DateStart, payP2.DateStop); //Validate List <TimeAdjust> resultList = TimeAdjusts.Refresh(emp.EmployeeNum, startDate, startDate.AddDays(28)); Assert.IsFalse(resultList.Count < 1); TimeAdjust result = resultList[0]; Assert.AreEqual(TimeSpan.FromHours(-4), result.RegHours); Assert.AreEqual(TimeSpan.FromHours(4), result.OTimeHours); }
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); }
protected static TaxPeriod GetPeriodFromNumber(PayPeriods periods, int period, int taxYear) { var baseDate = new DateTime(taxYear, 04, 06); var referenceDate = baseDate.AddDays(period * (365 / (int)periods)); return(new TaxPeriod(referenceDate)); }
public void TimeCardRules_CalculateWeeklyOvertime_ForDifferentClinicsRealData() { string suffix = "66"; DateTime startDate = DateTime.Parse("2016-05-09"); //This will create a pay period that splits a work week. Employee emp = EmployeeT.CreateEmployee(suffix); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 0); TimeCardRules.RefreshCache(); //Each of these are 11 hour days. Should have 4 hours of OT with clinic 3 in the second pay period and 11 hours for clinic 4. //Week 1 - 40.4 hours long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(0).AddHours(6), startDate.AddDays(0).AddHours(6 + 8), 0); //Mon long clockEvent2 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(1).AddHours(6), startDate.AddDays(1).AddHours(6 + 8), 0); //Tue long clockEvent3 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(2).AddHours(6), startDate.AddDays(2).AddHours(6 + 8.76), 0, 0.06); //Wed long clockEvent4 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(3).AddHours(6), startDate.AddDays(3).AddHours(6 + 8.72), 0, 0.73); //Thurs long clockEvent5 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(4).AddHours(6), startDate.AddDays(4).AddHours(6 + 8.12), 0, 0.41); //Fri //Week 2 - 41.23 hours long clockEvent6 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(7).AddHours(6), startDate.AddDays(7).AddHours(6 + 8.79), 0, 0.4); //Mon long clockEvent7 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(8).AddHours(6), startDate.AddDays(8).AddHours(6 + 8.85), 0, 0.38); //Tue long clockEvent8 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(9).AddHours(6), startDate.AddDays(9).AddHours(6 + 7.78), 0, 0.29); //Wed long clockEvent9 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(10).AddHours(6), startDate.AddDays(10).AddHours(6 + 8.88), 0, 0.02); //Thurs long clockEvent10 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(11).AddHours(6), startDate.AddDays(11).AddHours(6 + 8.59), 0, 0.57); //Fri TimeCardRules.CalculateWeeklyOvertime(emp, payP1.DateStart, payP1.DateStop); //Validate List <TimeAdjust> listAdjusts = TimeAdjusts.GetValidList(emp.EmployeeNum, startDate, startDate.AddDays(28)).OrderBy(x => x.OTimeHours).ToList(); Assert.AreEqual(2, listAdjusts.Count); Assert.AreEqual(TimeSpan.FromHours(-0.4), listAdjusts[0].RegHours); Assert.AreEqual(TimeSpan.FromHours(0.4), listAdjusts[0].OTimeHours); Assert.AreEqual(TimeSpan.FromHours(-1.23), listAdjusts[1].RegHours); Assert.AreEqual(TimeSpan.FromHours(1.23), listAdjusts[1].OTimeHours); }
public void TimeCardRules_CalculateWeeklyOvertime_OneWeekOverTwoPayPeriodsForDifferentClinicPreferences() { string suffix = "64"; DateTime startDate = DateTime.Parse("2001-02-01"); //This will create a pay period that splits a work week. Employee emp = EmployeeT.CreateEmployee(suffix); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriod payP2 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate.AddDays(14)); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 0); TimeCardRules.RefreshCache(); //Each of these are 11 hour days. Should have 4 hours of OT with clinic 3 in the second pay period and 11 hours for clinic 4. long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(10).AddHours(6), startDate.AddDays(10).AddHours(17), 0); //Sun long clockEvent2 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(11).AddHours(6), startDate.AddDays(11).AddHours(17), 1); //Mon long clockEvent3 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(12).AddHours(6), startDate.AddDays(12).AddHours(17), 2); //Tue //new pay period long clockEvent4 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(14).AddHours(6), startDate.AddDays(14).AddHours(17), 3); //Wed long clockEvent5 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(15).AddHours(6), startDate.AddDays(15).AddHours(17), 4); //Thurs TimeCardRules.CalculateWeeklyOvertime(emp, payP1.DateStart, payP1.DateStop); TimeCardRules.CalculateWeeklyOvertime(emp, payP2.DateStart, payP2.DateStop); //Validate List <TimeAdjust> listAdjusts = TimeAdjusts.GetValidList(emp.EmployeeNum, startDate, startDate.AddDays(28)).OrderBy(x => x.OTimeHours).ToList(); Assert.AreEqual(2, listAdjusts.Count); Assert.AreEqual(TimeSpan.FromHours(-4), listAdjusts[0].RegHours); Assert.AreEqual(3, listAdjusts[0].ClinicNum); Assert.AreEqual(TimeSpan.FromHours(4), listAdjusts[0].OTimeHours); Assert.AreEqual(TimeSpan.FromHours(-11), listAdjusts[1].RegHours); Assert.AreEqual(4, listAdjusts[1].ClinicNum); Assert.AreEqual(TimeSpan.FromHours(11), listAdjusts[1].OTimeHours); }
public void TimeCardRules_CalculateWeeklyOvertime_ForDifferentClinics() { string suffix = "62"; DateTime startDate = DateTime.Parse("2001-01-01"); Employee emp = EmployeeT.CreateEmployee(suffix); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 0); TimeCardRules.RefreshCache(); //Each of these are 11 hour days. Should have 4 hours of OT with clinic 3 and 11 hours OT with clinic 4 the end of the pay period. long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(0).AddHours(6), startDate.AddDays(0).AddHours(17), 0); long clockEvent2 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(1).AddHours(6), startDate.AddDays(1).AddHours(17), 1); long clockEvent3 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(2).AddHours(6), startDate.AddDays(2).AddHours(17), 2); long clockEvent4 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(3).AddHours(6), startDate.AddDays(3).AddHours(17), 3); long clockEvent5 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(4).AddHours(6), startDate.AddDays(4).AddHours(17), 4); TimeCardRules.CalculateWeeklyOvertime(emp, payP1.DateStart, payP1.DateStop); //Validate List <TimeAdjust> listAdjusts = TimeAdjusts.GetValidList(emp.EmployeeNum, startDate, startDate.AddDays(5)).OrderBy(x => x.OTimeHours).ToList(); Assert.AreEqual(2, listAdjusts.Count); Assert.AreEqual(TimeSpan.FromHours(-4), listAdjusts[0].RegHours); Assert.AreEqual(3, listAdjusts[0].ClinicNum); Assert.AreEqual(TimeSpan.FromHours(4), listAdjusts[0].OTimeHours); Assert.AreEqual(TimeSpan.FromHours(-11), listAdjusts[1].RegHours); Assert.AreEqual(4, listAdjusts[1].ClinicNum); Assert.AreEqual(TimeSpan.FromHours(11), listAdjusts[1].OTimeHours); }
public void TimeCardRules_CalculateWeeklyOvertime_OneWeekWorkWeekStartsOnWednesday() { string suffix = "27"; DateTime startDate = DateTime.Parse("2001-01-01"); Employee emp = EmployeeT.CreateEmployee(suffix); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 3); TimeCardRules.RefreshCache(); long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(0).AddHours(6), startDate.AddDays(0).AddHours(17), 0); long clockEvent2 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(1).AddHours(6), startDate.AddDays(1).AddHours(17), 0); //new work week long clockEvent3 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(2).AddHours(6), startDate.AddDays(2).AddHours(17), 0); long clockEvent4 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(3).AddHours(6), startDate.AddDays(3).AddHours(17), 0); long clockEvent5 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(4).AddHours(6), startDate.AddDays(4).AddHours(17), 0); long clockEvent6 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(5).AddHours(6), startDate.AddDays(5).AddHours(17), 0); TimeCardRules.CalculateWeeklyOvertime(emp, payP1.DateStart, payP1.DateStop); //Validate TimeAdjust result = TimeAdjusts.Refresh(emp.EmployeeNum, startDate, startDate.AddDays(28))[0]; Assert.AreEqual(TimeSpan.FromHours(-4), result.RegHours); Assert.AreEqual(TimeSpan.FromHours(4), result.OTimeHours); }
/// <summary> /// Get Period Based Factors for TaxMath.Factor /// </summary> /// <param name="payPeriods">Pay Periods</param> /// <returns>Name Value Tuple for Periods / WeeksInPeriod</returns> public static (int Periods, int WeeksInPeriod) GetFactoring(PayPeriods payPeriods) { if (payPeriods == PayPeriods.Monthly) { return(12, 1); } else { return(52, (int)Math.Round((decimal)52 / (int)payPeriods)); } }
protected decimal TestShim(int year, StudentLoanPlan plan, decimal gross, PayPeriods periods) { if (CalculationEngine == null) { CalculationEngine = new StudentLoans(); CalculationEngine.SetTaxYearSpecificsProvider(new JsonTaxYearSpecificProvider()); } CalculationEngine.SetTaxYear(year); return(CalculationEngine.CalculateStudentLoanDeduction(plan, gross, periods).StudentLoanDeduction); }
protected decimal LegacyShim(decimal gross, string taxCode, PayPeriods periods, int period, decimal gtd, decimal ttd, bool wk1, int year) { if (!CalcEngines.ContainsKey(year)) { CalcEngines.Add(year, DefaultEngineResolver.GetEngine <IPayeCalculationEngine>(year)); CalcEngines[year].SetTaxYearSpecificsProvider(new JsonTaxYearSpecificProvider()); CalcEngines[year].SetTaxYear(year); } return(CalcEngines[year].CalculateTaxDueForPeriod(taxCode, gross, periods, period, wk1, gtd, ttd)); }
protected decimal TestShim(decimal gross, char niCode, PayPeriods periods, int year) { if (!CalcEngines.ContainsKey(year)) { CalcEngines.Add(year, DefaultEngineResolver.GetEngine <INiCalculationEngine>(year)); CalcEngines[year].SetTaxYearSpecificsProvider(new JsonTaxYearSpecificProvider()); CalcEngines[year].SetTaxYear(year); } var result = CalcEngines[year].CalculateNationalInsurance(gross, niCode, periods); return(result.EmployeeNi + result.EmployerNi); }
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)), }); }
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)), }); }
/// <summary> /// Get Period Based Factors for TaxMath.Factor /// </summary> /// <param name="payPeriods">Pay Periods</param> /// <returns>Name Value Tuple for Periods / WeeksInPeriod</returns> public static PeriodFactoring GetFactoring(PayPeriods payPeriods) { int periods = 12, weeksInPeriod = 1; if (payPeriods != PayPeriods.Monthly) { periods = 52; weeksInPeriod = (int)Math.Round((decimal)52 / (int)payPeriods); } return(new PeriodFactoring { Periods = periods, WeeksInPeriod = weeksInPeriod }); }
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 void TimeCardRules_CalculateWeeklyOvertime_CalculationWithManualOvertime() { string suffix = "67"; DateTime startDate = DateTime.Parse("2016-03-14"); Employee emp = EmployeeT.CreateEmployee(suffix); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 0); TimeCardRules.RefreshCache(); //Each of these are 11 hour days. Should have 4 hours of OT with clinic 3 in the second pay period and 11 hours for clinic 4. //Week 1 - 40.13 (Note: These appear as they should after CalculateDaily is run.) long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(0).AddHours(6), startDate.AddDays(0).AddHours(6 + 8.06), 0); //Mon long clockEvent2 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(1).AddHours(6), startDate.AddDays(1).AddHours(6 + 8), 0); //Tue long clockEvent3 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(2).AddHours(6), startDate.AddDays(2).AddHours(6 + 8.08), 0); //Wed long clockEvent4 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(3).AddHours(6), startDate.AddDays(3).AddHours(6 + 8), 0, 0.02); //Thurs long clockEvent5 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(4).AddHours(6), startDate.AddDays(4).AddHours(6 + 8.01), 0); //Fri //SATURDAY - 4.1 HRS OF OVERTIME ClockEvent ce = new ClockEvent(); ce.ClinicNum = 0; ce.ClockStatus = TimeClockStatus.Home; ce.EmployeeNum = emp.EmployeeNum; ce.OTimeHours = TimeSpan.FromHours(4.1); ce.TimeDisplayed1 = new DateTime(startDate.Year, startDate.Month, startDate.AddDays(5).Day, 6, 54, 0); ce.TimeDisplayed2 = new DateTime(startDate.Year, startDate.Month, startDate.AddDays(5).Day, 11, 0, 0); ce.TimeEntered1 = ce.TimeDisplayed1; ce.TimeEntered2 = ce.TimeDisplayed2; ce.ClockEventNum = ClockEvents.Insert(ce); ClockEvents.Update(ce); //Week 2 - 41.06 long clockEvent6 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(7).AddHours(6), startDate.AddDays(7).AddHours(6 + 8.02), 0); //Mon long clockEvent7 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(8).AddHours(6), startDate.AddDays(8).AddHours(6 + 8), 0); //Tue long clockEvent8 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(9).AddHours(6), startDate.AddDays(9).AddHours(6 + 8), 0); //Wed long clockEvent9 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(10).AddHours(6), startDate.AddDays(10).AddHours(6 + 9.04), 0); //Thurs long clockEvent10 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(11).AddHours(6), startDate.AddDays(11).AddHours(6 + 8), 0); //Fri TimeCardRules.CalculateWeeklyOvertime(emp, payP1.DateStart, payP1.DateStop); //Validate List <TimeAdjust> listAdjusts = TimeAdjusts.GetValidList(emp.EmployeeNum, startDate, startDate.AddDays(28)).OrderBy(x => x.OTimeHours).ToList(); Assert.AreEqual(2, listAdjusts.Count); Assert.AreEqual(TimeSpan.FromHours(-0.13), listAdjusts[0].RegHours); Assert.AreEqual(TimeSpan.FromHours(0.13), listAdjusts[0].OTimeHours); Assert.AreEqual(TimeSpan.FromHours(-1.06), listAdjusts[1].RegHours); Assert.AreEqual(TimeSpan.FromHours(1.06), listAdjusts[1].OTimeHours); }
private PayPeriods GetNoneItemofPayPeriods() { try { PayPeriods objPayPeriods = new PayPeriods { Calendar_Period_ID = 0, Calendar_Period = "Please Select", }; return(objPayPeriods); } catch (Exception ex) { ExceptionManager.Publish(ex); return(new PayPeriods()); } }
public void TimeCardRules_CalculateDailyOvertime_ForHoursWorkedBeforeACertainTime() { string suffix = "33"; DateTime startDate = DateTime.Parse("2001-01-01"); Employee emp = EmployeeT.CreateEmployee(suffix); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 0); Prefs.UpdateBool(PrefName.TimeCardsMakesAdjustmentsForOverBreaks, true); TimeCardRuleT.CreateAMTimeRule(emp.EmployeeNum, TimeSpan.FromHours(7.5)); TimeCardRules.RefreshCache(); long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddHours(6), startDate.AddHours(16), 0); ClockEventT.InsertBreak(emp.EmployeeNum, startDate.AddHours(11), 40, 0); CalculateDailyOvertime(emp, payP1.DateStart, payP1.DateStop); //Validate Assert.AreEqual(TimeSpan.FromMinutes(-10), ClockEvents.GetOne(clockEvent1).AdjustAuto); Assert.AreEqual(TimeSpan.FromMinutes(90), ClockEvents.GetOne(clockEvent1).Rate2Auto); }
private PayPeriods GetNoneItemofPayPeriods() { try { PayPeriods objPayPeriods = new PayPeriods { Calendar_Period_ID = 0, Date = "Please Select", Calendar_Period_Start_Date = DateTime.MinValue, Calendar_Period_End_Date = DateTime.MinValue }; return(objPayPeriods); } catch (Exception ex) { ExceptionManager.Publish(ex); return(new PayPeriods()); } }
private void LoadPayPeriods() { try { lstPayPeriods = oProfitShareConfiguration.GetPayPeriods(); objPayPeriods = lstPayPeriods.Where(item => item.Calendar_Period_Start_Date <= DateTime.Today && item.Calendar_Period_End_Date >= DateTime.Today).FirstOrDefault() as PayPeriods; if (objPayPeriods == null) { objPayPeriods = new PayPeriods(); return; } ; txtblkPayPeriod.Text = objPayPeriods.Calendar_Period; } catch (Exception ex) { ExceptionManager.Publish(ex); } }
public void TimeCardRules_CalculateDailyOvertime_WhileEmployeeClockedInTodayDuringPayPeriod() { DateTime startDate = DateTime.Now.Date.AddDays(-1); Employee emp = EmployeeT.CreateEmployee("CalculateDailyWhileEmployeeClockedInDuringPayPeriod"); PayPeriod payP1 = PayPeriodT.CreateTwoWeekPayPeriodIfNotExists(startDate); PayPeriods.RefreshCache(); Prefs.UpdateInt(PrefName.TimeCardOvertimeFirstDayOfWeek, 0); Prefs.UpdateBool(PrefName.TimeCardsMakesAdjustmentsForOverBreaks, true); Prefs.RefreshCache(); TimeCardRules.RefreshCache(); //10 hour day with 45 minute break long clockEvent1 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddHours(8), startDate.AddHours(18)); long break1 = ClockEventT.InsertBreak(emp.EmployeeNum, startDate.AddHours(12), 45); //Next day clock in, but have no clock out event yet. long clockEvent2 = ClockEventT.InsertWorkPeriod(emp.EmployeeNum, startDate.AddDays(1).AddHours(8), DateTime.MinValue); CalculateDailyOvertime(emp, payP1.DateStart, payP1.DateStop); //Ensure that the 15 minutes was subtracted from the shift. Assert.AreEqual(TimeSpan.FromMinutes(-15), ClockEvents.GetOne(clockEvent1).AdjustAuto); }
private PayPeriods GetNoneItemofPayPeriods() { try { PayPeriods objPayPeriods = new PayPeriods { Calendar_Period_ID = 0, Calendar_Period = "Please Select", }; return objPayPeriods; } catch (Exception ex) { ExceptionManager.Publish(ex); return new PayPeriods(); } }
public override decimal CalculateTaxDueForPeriod(TaxCode taxCode, decimal gross, PayPeriods periods, int period, bool week1 = false, decimal grossToDate = 0, decimal taxToDate = 0) { CreateContainer(taxCode, gross, periods, period, week1, grossToDate, taxToDate); CalculateTax(); return(CalculationContainer.ln); }
public abstract NationalInsuranceCalculation CalculateNationalInsurance(decimal gross, char niCategory, PayPeriods payPeriods);
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 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 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) { // 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); }
private PayPeriods GetNoneItemofPayPeriods() { try { PayPeriods objPayPeriods = new PayPeriods { Calendar_Period_ID = 0, Date = "Please Select", Calendar_Period_Start_Date = DateTime.MinValue, Calendar_Period_End_Date = DateTime.MinValue }; return objPayPeriods; } catch (Exception ex) { ExceptionManager.Publish(ex); return new PayPeriods(); } }
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); }
private void LoadPayPeriods() { try { lstPayPeriods = oProfitShareConfiguration.GetPayPeriods(); objPayPeriods = lstPayPeriods.Where(item => item.Calendar_Period_Start_Date <= DateTime.Today && item.Calendar_Period_End_Date >= DateTime.Today).FirstOrDefault() as PayPeriods; if (objPayPeriods == null) { objPayPeriods = new PayPeriods(); return; }; txtblkPayPeriod.Text = objPayPeriods.Calendar_Period; } catch (Exception ex) { ExceptionManager.Publish(ex); } }
/// <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)); }
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); }