Create an instance of Calculator
, providing values as per the following example:
val calculator = Calculator(
taxCode = "1257L", // Required
userSuppliedTaxCode = false, // Optional (Default: true)
wages = 20000.0, // Required
payPeriod = YEARLY, // Required
isPensionAge = false, // Optional (Default: false)
howManyAWeek = null, // Optional (Default: null)
taxYear = TaxYear.currentTaxYear, // Optional (Default: Current Tax Year)
pensionMethod = PERCENTAGE, // Optional (Default: null)
pensionYearlyAmount = null, // Optional (Default: null)
pensionPercentage = 10.0, // Optional (Default: null)
hasStudentLoanPlanOne = false, // Optional (Default: false)
hasStudentLoanPlanTwo = false, // Optional (Default: false)
hasStudentLoanPlanFour = false, // Optional (Default: false)
hasStudentLoanPostgraduatePlan = false, // Optional (Default: false)
)
val response = calculator.run()
let calculator = Calculator(
taxCode: "1257L",
userSuppliedTaxCode = false,
wages: 20000.0,
payPeriod: period,
isPensionAge: false,
howManyAWeek: KotlinDouble(double: 35),
taxYear: TaxYear.companion.currentTaxYear,
pensionMethod: pensionMethod,
pensionYearlyAmount: KotlinDouble(double: 0),
pensionPercentage: KotlinDouble(double: 10),
hasStudentLoanPlanOne: false,
hasStudentLoanPlanTwo: false,
hasStudentLoanPlanFour: false,
hasStudentLoanPostgraduatePlan: false
)
let calculation = try calculator.run()
The default values are working in Android (and other JVM) but currently do not seem to be present in iOS, so pass in the default values for now.
Returns an object of type CalculatorResponse
. This class is broken up into weekly
, four_weekly
, monthly
and yearly
. Each of these members is of type CalculatorResponsePayPeriod
and the members of this class are what will return the values (relative to their PayPeriod) needed for the app, they are:
taxToPay
of type Double
(This will be capped at a maximum of 50% of their wages)userSuppliedTaxCode
of type Boolean
(If this value is true
, tapering will not apply in the calculation)maxTaxAmountExceeded
of type Boolean
(This will always be false unless taxToPay is adjusted for 50%)employeesNI
of type Double
employersNI
of type Double
wages
of type Double
taxBreakdown
of type List<BandBreakdown>
taxFree
of type Double
totalDeductions
of type Double
takeHome
of type Double
pensionContribution
of type Double
(This will return 0.0 if no Pension being added)taperingAmountDeduction
of type Double
(This will return 0.0 if wage is below £100,002)studentLoanBreakdown
of type List<StudentLoanAmountBreakdown>
(This will return null if no student loan plan)finalStudentLoanAmount
of type Double
(This will return 0.0 if no student loan plan)For tax breakdown this is the amount of tax per tax band which has two members,
percentage: Double
andamount: Double
.
val taxCode = CalculatorUtils.defaultTaxCode(taxYear = 2022)
let taxCode = CalculatorUtils.shared.defaultTaxCode(taxYear: 2022)
val year = CalculatorUtils.currentTaxYear()
let year = CalculatorUtils.shared.currentTaxYear()
val isValid = TaxCodeValidator.isValidTaxCode(taxCode = "1257L") // TaxCodeValidationResponse(true)
val isValid = TaxCodeValidator.isValidTaxCode(taxCode = "OO9999") // TaxCodeValidationResponse(false, ValidationError.WrongTaxCodePrefix)
val isValid = TaxCodeValidator.isValidTaxCode(taxCode = "9999R") // TaxCodeValidationResponse(false, ValidationError.WrongTaxCodeSuffix)
val isValid = TaxCodeValidator.isValidTaxCode(taxCode = "HELLO") // TaxCodeValidationResponse(false, ValidationError.WrongTaxCodeNumber)
val isValid = TaxCodeValidator.isValidTaxCode(taxCode = "110") // TaxCodeValidationResponse(false, ValidationError.Other)
let isValid = TaxCodeValidator.shared.isValidTaxCode(taxCode: "1257L") // TaxCodeValidationResponse(true)
let isValid = TaxCodeValidator.shared.isValidTaxCode(taxCode: "OO9999") // TaxCodeValidationResponse(false, ValidationError.WrongTaxCodePrefix)
let isValid = TaxCodeValidator.shared.isValidTaxCode(taxCode: "9999R") // TaxCodeValidationResponse(false, ValidationError.WrongTaxCodeSuffix)
let isValid = TaxCodeValidator.shared.isValidTaxCode(taxCode: "HELLO") // TaxCodeValidationResponse(false, ValidationError.WrongTaxCodeNumber)
let isValid = TaxCodeValidator.shared.isValidTaxCode(taxCode: "110") // TaxCodeValidationResponse(false, ValidationError.Other)
val isValidWages = WageValidator.isValidWages(wages = 1000) // true
val isAboveMinimumWages = WageValidator.isAboveMinimumWages(wages = 0.0) // false
val isBelowMaximumWages = WageValidator.isBelowMaximumWages(wages = 120000.0) // true
let isValidWages = WageValidator.shared.isValidWages(wages: 1000) // true
let isAboveMinimumWages = WageValidator.shared.isAboveMinimumWages(wages: 0.0) // false
let isBelowMaximumWages = WageValidator.shared.isBelowMaximumWages(wages: 120000.0) // true
val isValidHoursPerWeek = HoursDaysValidator.isValidHoursPerWeek(hours = 20) // true
val isAboveMinimumHoursPerWeek = HoursDaysValidator.isAboveMinimumHoursPerWeek(hours = 1.0) // true
val isBelowMaximumHoursPerWeek = HoursDaysValidator.isBelowMaximumHoursPerWeek(hours = 170.0) // false
val isValidHoursPerDay = HoursDaysValidator.isValidHoursPerDay(hours = 20) // true
val isAboveMinimumHoursPerDay = HoursDaysValidator.isAboveMinimumHoursPerDay(hours = 1.0) // true
val isBelowMaximumHoursPerDay = HoursDaysValidator.isBelowMaximumHoursPerDay(hours = 25.0) // false
let isValidHoursPerWeek = HoursDaysValidator.shared.isValidHoursPerWeek(hours: 20) // true
let isAboveMinimumHoursPerWeek = HoursDaysValidator.shared.isAboveMinimumHoursPerWeek(hours: 1.0) // true
let isBelowMaximumHoursPerWeek = HoursDaysValidator.shared.isBelowMaximumHoursPerWeek(hours: 170.0) // false
let isValidHoursPerDay = HoursDaysValidator.shared.isValidHoursPerDay(hours: 20) // true
let isAboveMinimumHoursPerDay = HoursDaysValidator.shared.isAboveMinimumHoursPerDay(hours: 1.0) // true
let isBelowMaximumHoursPerDay = HoursDaysValidator.shared.isBelowMaximumHoursPerDay(hours: 25.0) // false
To run all tests and coverage verification:
./gradlew check
Because this operates as a closed source, binary dependency, Swift PM will only work with tagged releases and not branches.
https://github.com/hmrc/tax-kalculator
Add the Github Package repository to your top-level build.gradle
, along with a Github username and access token (no permissions required).
repositories {
maven {
url = "https://maven.pkg.github.com/hmrc/tax-kalculator"
credentials {
username = System.getenv("GITHUB_USER_NAME")
password = System.getenv("GITHUB_TOKEN")
}
}
}
Add the dependency in the build.gradle
of the module:
dependencies {
implementation "uk.gov.hmrc:tax-kalculator-jvm:x.y.z"
}
bundle exec fastlane tag_release
BITRISE_TOKEN
. See Bitrise docs.TAX_KALC_APP_SLUG
& TAX_KALC_RELEASE_WORKFLOW_ID
will also need to be included in your bash/ZSH profile. Speak with Chris to obtain these values.main
branchbuild_xcframework.sh
:
Package.swift
and CHANGELOG.md
release.sh
to start the CI pipeline on CI.Note: As part of updating the rates, we should also check our dependencies are up-to-date. For build issues, make sure the project has updated to the right kotlin version for the version of Xcode you are running. See: https://kotlinlang.org/docs/multiplatform-compatibility-guide.html#version-compatibility
Each tax band is represented with the following data structure:
internal data class TaxBand(
override var lower: Double, // lower threshold of band
override var upper: Double, // upper threshold of band
override val percentageAsDecimal: Double // tax rate of band
) : Band
In TaxBands.kt
update bands as specified by the business.
Usually England and Wales have the same bands. Whereas Scotland's are different.
// England and Wales
private fun restOfUK2022Bands() = listOf(
TaxBand(0.0, 37700.00, 0.2),
TaxBand(37700.00, 150000.00, 0.4),
TaxBand(150000.0, -1.0, 0.45)
)
// Scotland
private fun scottish2022Bands() = listOf(
TaxBand(0.00, 2162.00, 0.19),
TaxBand(2162.00, 13118.00, 0.20),
TaxBand(13118.00, 31092.00, 0.21),
TaxBand(31092.00, 150000.00, 0.41),
TaxBand(150000.00, -1.0, 0.46)
)
Employee and Employer bands are represented with the following data structures:
internal data class EmployeeNIBand(
override var lower: Double, // lower threshold of band
override var upper: Double, // upper threshold of band
override val percentageAsDecimal: Double // tax rate of band
) : Band
internal data class EmployerNIBand(
override var lower: Double, // lower threshold of band
override var upper: Double, // upper threshold of band
override val percentageAsDecimal: Double // tax rate of band
) : Band
In EmployeeNIBands.kt
and EmployerNIBands.kt
update bands as specified by the business.
private val employeeNIBands2022: List<EmployeeNIBand> = listOf(
EmployeeNIBand(9880.0, 50270.00, 0.1325),
EmployeeNIBand(50270.0, -1.0, 0.0325)
)
private val employerNIBands2022: List<EmployerNIBand> = listOf(
EmployerNIBand(9100.0, 50270.00, 0.1505),
EmployerNIBand(50270.0, -1.0, 0.1505)
)
Pension contribute has a life time and annual allowance, which are represented with the following data structures:
internal data class PensionAllowance(
val standardLifetimeAllowance: Double,
val annualAllowance: Double
)
In PensionAllowances.kt
update allowance as specified by the business.
private fun pensionAllowance2022() = PensionAllowance(1073100.0, 40000.0)
private fun pensionAllowance2023() = PensionAllowance(1073100.0, 60000.0)
Student loan rate has a Threshold and Recovery rate (in percentage), which are represented with the following data structures:
internal data class StudentLoanRepayment(
val yearlyThreshold: Double,
val recoveryRatePercentage: Double,
)
In StudentLoanRate.kt
update rate as specified by the business.
private fun studentLoanRepaymentRate2023() = mapOf(
StudentLoanPlan.PLAN_ONE to StudentLoanRepayment(22015.0, 0.09),
StudentLoanPlan.PLAN_TWO to StudentLoanRepayment(27295.0, 0.09),
StudentLoanPlan.PLAN_FOUR to StudentLoanRepayment(27660.0, 0.09),
StudentLoanPlan.POST_GRADUATE_PLAN to StudentLoanRepayment(21000.0, 0.06),
)
This code is open source software licensed under the Apache 2.0 License.
link |
Stars: 14 |
Last commit: 17 hours ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics