public async Task AndCheckingAllowedVersusAttemtpedMinWage(WageUnit wageUnit, decimal allowedMinimumHourlyWage, decimal attemptedFixedWage, bool expectedIsValid) { var request = new CreateApprenticeshipRequest { WageType = WageType.CustomWageFixed, WageUnit = wageUnit, FixedWage = attemptedFixedWage, HoursPerWeek = 36, ExpectedStartDate = _fixture.CreateFutureDateTime() }; var context = GetValidationContextForProperty(request, req => req.FixedWage); _fixture = new Fixture().Customize(new AutoMoqCustomization()); _mockSelector = _fixture.Freeze <Mock <IGetMinimumWagesService> >(); _mockSelector .Setup(selector => selector.GetApprenticeMinimumWageRate(It.IsAny <DateTime>())) .Returns(allowedMinimumHourlyWage); _fixture.Inject <IHourlyWageCalculator>(new HourlyWageCalculator()); _validator = _fixture.Create <CreateApprenticeshipRequestValidator>(); var result = await _validator.ValidateAsync(context).ConfigureAwait(false); result.IsValid.Should().Be(expectedIsValid); if (!result.IsValid) { result.Errors.First().ErrorCode .Should().Be(ErrorCodes.CreateApprenticeship.FixedWage); result.Errors.First().ErrorMessage .Should().Be(ErrorMessages.CreateApprenticeship.FixedWageIsBelowApprenticeMinimumWage); } }
public decimal Calculate(decimal wageValue, WageUnit wageUnit, decimal hoursPerWeek) { if (hoursPerWeek <= 0) { throw new ArgumentOutOfRangeException(nameof(hoursPerWeek), hoursPerWeek, HoursPerWeekZeroErrorMessage); } decimal calculatedHourlyWage; switch (wageUnit) { case WageUnit.Weekly: calculatedHourlyWage = WageCalculator.GetHourRate(wageValue, SFA.DAS.VacancyServices.Wage.WageUnit.Weekly, hoursPerWeek); break; case WageUnit.Monthly: calculatedHourlyWage = WageCalculator.GetHourRate(wageValue, SFA.DAS.VacancyServices.Wage.WageUnit.Monthly, hoursPerWeek); break; case WageUnit.Annually: calculatedHourlyWage = WageCalculator.GetHourRate(wageValue, SFA.DAS.VacancyServices.Wage.WageUnit.Annually, hoursPerWeek); break; default: throw new ArgumentOutOfRangeException(nameof(wageUnit), wageUnit, IncorrectWageTypeErrorMessage); } return(calculatedHourlyWage); }
private static WageUnit CorrectWageUnit(WageType type, WageUnit unit) { switch (type) { case WageType.CustomRange: if (unit == WageUnit.NotApplicable) { return(WageUnit.Weekly); } return(unit); case WageType.LegacyText: case WageType.CompetitiveSalary: case WageType.ToBeAgreedUponAppointment: case WageType.Unwaged: return(WageUnit.NotApplicable); case WageType.Custom: switch (unit) { case WageUnit.Weekly: case WageUnit.Monthly: case WageUnit.Annually: case WageUnit.NotApplicable: return(unit); default: throw new ArgumentOutOfRangeException(nameof(Unit), $"Invalid Wage Unit: {unit}"); } case WageType.LegacyWeekly: default: return(WageUnit.Weekly); } }
public void ShouldGetTheCorrectWageUnitForCustomWages(WageUnit wageUnit, WageUnit expected) { var wage = new Wage(WageType.Custom, null, null, null, string.Empty, wageUnit, null, null); var actual = wage.Unit; actual.Should().Be(expected); }
public void ShouldGetDisplayAmountWithFrequencyPostfix(WageUnit wageUnit, decimal displayAmount, string expected) { // Act. var actual = WagePresenter.GetDisplayAmountWithFrequencyPostfix(WageType.Custom, displayAmount, null, null, null, wageUnit, null, null); // Assert. actual.Should().Be(expected); }
public void RunTestCases(WageUnit wageUnit, decimal minWage, double hoursPerWeek, decimal expectedResult) { var minimumWageCalculator = new HourlyWageCalculator(); var result = minimumWageCalculator.Calculate(minWage, wageUnit, (decimal)hoursPerWeek); result.Should().BeApproximately(expectedResult, 0.01m); }
public void ShouldGetHeaderDisplayTextForWageUnit(WageUnit wageUnit, string expected) { // Act. var actual = wageUnit.GetHeaderDisplayText(); // Assert. actual.Should().Be(expected); }
public void ShouldSetCorrectWageUnit(WageType type, WageUnit suppliedUnit, WageUnit expectedUnit) { //Arrange //Act var result = new Wage(type, null, null, null, null, suppliedUnit, null, null); //Assert result.Unit.Should().Be(expectedUnit); }
public void ShouldGetTheCorrectWageUnitForNonCustomWages(WageType wageType, WageUnit expected) { var wage = new Wage(wageType, null, null, null, string.Empty, WageUnit.NotApplicable, null, null); // Act. var actual = wage.Unit; // Assert. actual.Should().Be(expected); }
public void ShouldGetDisplayAmountWithFrequencyPostfix(WageUnit wageUnit, decimal displayAmount, string expected) { // Act. string actual = WagePresenter.GetDisplayTextFrequencyPostfix(WageType.Custom, wageUnit, new WageDetails() { Amount = displayAmount }); // Assert. actual.Should().Be(expected); }
public static string GetDisplayTextFrequencyPostfix(WageType type, WageUnit unit, WageDetails wageDetails) { string postfix = unit.GetWagePostfix(); string displayAmount = GetDisplayText(type, unit, wageDetails); if (string.IsNullOrWhiteSpace(displayAmount)) { return(postfix); } return($"{displayAmount} {postfix}"); }
public void ShouldGetDisplayAmountWithFrequencyPostfixNationalMinimums(WageUnit wageUnit, string expected) { // Act. string actual = WagePresenter.GetDisplayTextFrequencyPostfix(WageType.ApprenticeshipMinimum, wageUnit, new WageDetails() { HoursPerWeek = 37.5m, StartDate = new DateTime(2016, 10, 30) }); // Assert. actual.Should().Be(expected); }
public void ShouldShowCustomWageAmount(decimal wage, WageUnit wageUnit, string expectedDisplayText) { var details = new WorkingWeekAndWage(); var viewModel = new VacancyViewModel() { ProviderSite = new ProviderSiteViewModel() { Address = new AddressViewModel() }, FurtherVacancyDetailsViewModel = new FurtherVacancyDetailsViewModel { VacancyDatesViewModel = new VacancyDatesViewModel { ClosingDate = new DateViewModel(DateTime.Now), PossibleStartDate = new DateViewModel(DateTime.Now) }, Wage = new WageViewModel() { Amount = wage, Unit = wageUnit } }, NewVacancyViewModel = new NewVacancyViewModel { VacancyOwnerRelationship = new VacancyOwnerRelationshipViewModel() { Employer = new EmployerViewModel() { Address = new AddressViewModel() } }, LocationAddresses = new List <VacancyLocationAddressViewModel>(), OfflineVacancy = false }, TrainingDetailsViewModel = new TrainingDetailsViewModel(), VacancyQuestionsViewModel = new VacancyQuestionsViewModel(), VacancyRequirementsProspectsViewModel = new VacancyRequirementsProspectsViewModel(), Status = VacancyStatus.Draft, VacancyType = VacancyType.Apprenticeship }; var view = details.RenderAsHtml(_context, viewModel); view.GetElementbyId("vacancy-wage").InnerHtml.Should().Be(expectedDisplayText); }
public static decimal GetHourRate(decimal wage, WageUnit wageUnit, decimal hoursPerWeek) { switch (wageUnit) { case WageUnit.Weekly: return(wage / hoursPerWeek); case WageUnit.Annually: return(wage / WageConstants.WeeksPerYear / hoursPerWeek); case WageUnit.Monthly: return(wage / WageConstants.WeeksPerYear * WageConstants.MonthPerYear / hoursPerWeek); case WageUnit.NotApplicable: return(0); default: throw new ArgumentOutOfRangeException(nameof(wageUnit), wageUnit, null); } }
private static string GetWagePostfix(this WageUnit wageUnit) { switch (wageUnit) { case WageUnit.Annually: return(WageConstants.PerYearText); case WageUnit.Monthly: return(WageConstants.PerMonthText); case WageUnit.Weekly: return(WageConstants.PerWeekText); case WageUnit.NotApplicable: return(string.Empty); default: throw new ArgumentOutOfRangeException(nameof(wageUnit), $"Invalid Wage Unit: {wageUnit}"); } }
public static string GetHeaderDisplayText(this WageUnit wageUnit) { switch (wageUnit) { case WageUnit.Annually: return(AnnualWageText); case WageUnit.Monthly: return(MonthlyWageText); case WageUnit.Weekly: return(WeeklyWageText); case WageUnit.NotApplicable: return(WageText); default: throw new ArgumentOutOfRangeException(nameof(wageUnit), $"Invalid Wage Unit: {wageUnit}"); } }
[TestCase(2652, WageUnit.Annually, 15, true)] //3.40 pounds per hour public void ApprenticeMinimumWage_PerHour_AfterOctFirst2016(decimal wage, WageUnit wageUnit, decimal hoursPerWeek, bool expectValid) { //After 1st of october 2016 the National Minimum Wage for Apprentices increases to £3.40/hour var viewModel = new FurtherVacancyDetailsViewModel { Wage = new WageViewModel() { Classification = WageClassification.Custom, CustomType = CustomWageType.Fixed, Amount = wage, Unit = wageUnit, HoursPerWeek = hoursPerWeek }, VacancyDatesViewModel = new VacancyDatesViewModel { PossibleStartDate = new DateViewModel(new DateTime(2016, 10, 1)) } }; var vacancyViewModel = new VacancyViewModelBuilder().With(viewModel).Build(); var response = _validator.Validate(viewModel, ruleSet: RuleSet); _aggregateValidator.Validate(vacancyViewModel); var aggregateResponse = _aggregateValidator.Validate(vacancyViewModel, ruleSet: RuleSet); if (expectValid) { _validator.ShouldNotHaveValidationErrorFor(vm => vm.Wage, vm => vm.Wage.Amount, viewModel, RuleSet); _aggregateValidator.ShouldNotHaveValidationErrorFor(vm => vm.FurtherVacancyDetailsViewModel, vm => vm.FurtherVacancyDetailsViewModel.Wage, vm => vm.FurtherVacancyDetailsViewModel.Wage.Amount, vacancyViewModel); _aggregateValidator.ShouldNotHaveValidationErrorFor(vm => vm.FurtherVacancyDetailsViewModel, vm => vm.FurtherVacancyDetailsViewModel.Wage, vm => vm.FurtherVacancyDetailsViewModel.Wage.Amount, vacancyViewModel, RuleSet); } else { _validator.ShouldHaveValidationErrorFor(vm => vm.Wage, vm => vm.Wage.Amount, viewModel, RuleSet); _aggregateValidator.ShouldHaveValidationErrorFor(vm => vm.FurtherVacancyDetailsViewModel, vm => vm.FurtherVacancyDetailsViewModel.Wage, vm => vm.FurtherVacancyDetailsViewModel.Wage.Amount, vacancyViewModel); _aggregateValidator.ShouldHaveValidationErrorFor(vm => vm.FurtherVacancyDetailsViewModel, vm => vm.FurtherVacancyDetailsViewModel.Wage, vm => vm.FurtherVacancyDetailsViewModel.Wage.Amount, vacancyViewModel, RuleSet); var error = response.Errors.SingleOrDefault(e => e.PropertyName == "Wage.Amount"); error.Should().NotBeNull(); error?.ErrorMessage.Should().Be("The wage should not be less then the new National Minimum Wage for apprentices effective from 1 Oct 2016"); var aggregateError = aggregateResponse.Errors.SingleOrDefault(e => e.PropertyName == "FurtherVacancyDetailsViewModel.Wage.Amount"); aggregateError.Should().NotBeNull(); aggregateError?.ErrorMessage.Should().Be("The wage should not be less then the new National Minimum Wage for apprentices effective from 1 Oct 2016"); } }
public async Task AndCallingValidate(WageUnit wageUnitToValidate, bool expectedIsValid, string expectedErrorCodes, string expectedErrorMessages) { var fixture = new Fixture().Customize(new AutoMoqCustomization()); var request = new CreateApprenticeshipRequest { WageUnit = wageUnitToValidate }; var context = GetValidationContextForProperty(request, req => req.WageUnit); var validator = fixture.Create <CreateApprenticeshipRequestValidator>(); var result = await validator.ValidateAsync(context); result.IsValid.Should().Be(expectedIsValid); if (!expectedIsValid) { result.Errors.First().ErrorCode .Should().Be(expectedErrorCodes); result.Errors.First().ErrorMessage .Should().Be(expectedErrorMessages); } }
public static decimal GetHourRateRoundAsMoney(decimal wage, WageUnit wageUnit, decimal hoursPerWeek) { return(RoundAsMoney(GetHourRate(wage, wageUnit, hoursPerWeek))); }
public Wage(WageType type, decimal?amount, decimal?amountLowerBound, decimal?amountUpperBound, string text, WageUnit unit, decimal?hoursPerWeek, string reasonForType) { Type = type; Amount = amount; AmountLowerBound = amountLowerBound; AmountUpperBound = amountUpperBound; ReasonForType = reasonForType; Text = text; HoursPerWeek = hoursPerWeek; Unit = CorrectWageUnit(type, unit); }
public static string GetDisplayText(WageType type, WageUnit unit, WageDetails details) { WageDetails wageDetails = details ?? new WageDetails(); switch (type) { case WageType.Custom: return(FormatWageAmount(wageDetails.Amount)); case WageType.ApprenticeshipMinimum: if (!wageDetails.HoursPerWeek.HasValue || wageDetails.HoursPerWeek.Value == 0) { return($"£{WageConstants.UnknownText}"); } if (unit == WageUnit.Annually) { return(GetYearlyApprenticeshipMinimumWage(wageDetails.HoursPerWeek.Value, wageDetails.StartDate)); } return(GetWeeklyApprenticeshipMinimumWage(wageDetails.HoursPerWeek.Value, wageDetails.StartDate)); case WageType.NationalMinimum: if (!wageDetails.HoursPerWeek.HasValue || wageDetails.HoursPerWeek.Value == 0) { return($"£{WageConstants.UnknownText}"); } if (unit == WageUnit.Annually) { return(GetYearlyNationalMinimumWage(wageDetails.HoursPerWeek.Value, wageDetails.StartDate)); } return(GetWeeklyNationalMinimumWage(wageDetails.HoursPerWeek.Value, wageDetails.StartDate)); case WageType.Text: //if it's unknown, return standard unknown text string displayText = wageDetails.Text ?? $"£{WageConstants.UnknownText}"; //if it's not unknown, then prepend a '£' sign to its decimal value. decimal wageDecimal; //if it's already got a '£' sign, or is text, fail to parse and all is good => return value. if (decimal.TryParse(displayText, out wageDecimal)) { displayText = FormatWageAmount(wageDecimal); } return(displayText); case WageType.CustomRange: return ($"{FormatWageAmount(wageDetails.LowerBound)} - {FormatWageAmount(wageDetails.UpperBound)}"); case WageType.CompetitiveSalary: return(WageConstants.CompetitiveSalaryText); case WageType.ToBeAgreedUponAppointment: return(WageConstants.ToBeAGreedUponAppointmentText); case WageType.Unwaged: return(WageConstants.UnwagedText); default: throw new ArgumentOutOfRangeException(nameof(type), type, $"Invalid Wage Type: {type}"); } }
public static string GetDisplayAmountWithFrequencyPostfix(WageType type, decimal?amount, decimal?amountLowerBound, decimal?amountUpperBound, string text, WageUnit unit, decimal?hoursPerWeek, DateTime?possibleDateTime) { var postfix = unit.GetWagePostfix(); var displayAmount = GetDisplayAmount(type, amount, amountLowerBound, amountUpperBound, text, hoursPerWeek, possibleDateTime); if (string.IsNullOrWhiteSpace(displayAmount)) { return(postfix); } return($"{displayAmount} {postfix}"); }