From 9cf1954964a8d55e3452e54fc1262840ec13e681 Mon Sep 17 00:00:00 2001 From: Aidan Sullivan Date: Thu, 12 Mar 2020 08:21:15 -0500 Subject: [PATCH] LAWS-178 mn tax changes --- .../V20200101/MinnesotaIncome.php | 56 ++++++++++ .../V20200101/MinnesotaUnemployment.php | 19 ++++ .../MinnesotaIncomeTaxInformation.php | 1 + ...rs_to_minnesota_tax_income_information.php | 17 +++ .../V20200101/MinnesotaIncomeTest.php | 104 ++++++++++++++++++ .../V20200101/MinnesotaUnemploymentTest.php | 61 ++++++++++ 6 files changed, 258 insertions(+) create mode 100644 src/Countries/US/Minnesota/MinnesotaIncome/V20200101/MinnesotaIncome.php create mode 100644 src/Countries/US/Minnesota/MinnesotaUnemployment/V20200101/MinnesotaUnemployment.php create mode 100644 src/migrations/2020_03_12_000000_add_parameters_to_minnesota_tax_income_information.php create mode 100644 tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaIncomeTest.php create mode 100644 tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaUnemploymentTest.php diff --git a/src/Countries/US/Minnesota/MinnesotaIncome/V20200101/MinnesotaIncome.php b/src/Countries/US/Minnesota/MinnesotaIncome/V20200101/MinnesotaIncome.php new file mode 100644 index 000000000..859724884 --- /dev/null +++ b/src/Countries/US/Minnesota/MinnesotaIncome/V20200101/MinnesotaIncome.php @@ -0,0 +1,56 @@ +tax_information->filing_status === 'S') { + return self::SINGLE_TAX_WITHHOLDING_BRACKET; + } + + return self::MARRIED_TAX_WITHHOLDING_BRACKET; + } + + public function compute(Collection $tax_areas) + { + if ($this->isUserClaimingExemption()) { + return 0; + } + + $this->tax_total = $this->payroll->withholdTax($this->getTaxAmountFromTaxBrackets($this->getGrossWages() - $this->getWithholdingAllowances(), $this->getTaxBrackets()) / $this->payroll->pay_periods + $this->tax_information->additional_withholding); + + return round($this->tax_total, 2); + } + + public function getGrossWages() + { + return $this->getAdjustedEarnings() * $this->payroll->pay_periods; + } + + public function getWithholdingAllowances() + { + return $this->tax_information->allowances * self::WITHHOLDING_ALLOWANCE; + } +} diff --git a/src/Countries/US/Minnesota/MinnesotaUnemployment/V20200101/MinnesotaUnemployment.php b/src/Countries/US/Minnesota/MinnesotaUnemployment/V20200101/MinnesotaUnemployment.php new file mode 100644 index 000000000..044bf59a4 --- /dev/null +++ b/src/Countries/US/Minnesota/MinnesotaUnemployment/V20200101/MinnesotaUnemployment.php @@ -0,0 +1,19 @@ +tax_rate = config('taxes.rates.us.minnesota.unemployment', static::NEW_EMPLOYER_RATE); + } +} diff --git a/src/Models/Countries/US/Minnesota/MinnesotaIncomeTaxInformation.php b/src/Models/Countries/US/Minnesota/MinnesotaIncomeTaxInformation.php index eba4dc690..ac8a8ed21 100644 --- a/src/Models/Countries/US/Minnesota/MinnesotaIncomeTaxInformation.php +++ b/src/Models/Countries/US/Minnesota/MinnesotaIncomeTaxInformation.php @@ -12,6 +12,7 @@ class MinnesotaIncomeTaxInformation extends BaseTaxInformationModel public static function getDefault() { $tax_information = new self(); + $tax_information->additional_withholding = 0; $tax_information->allowances = 0; $tax_information->filing_status = 0; $tax_information->exempt = MinnesotaIncome::FILING_SINGLE; diff --git a/src/migrations/2020_03_12_000000_add_parameters_to_minnesota_tax_income_information.php b/src/migrations/2020_03_12_000000_add_parameters_to_minnesota_tax_income_information.php new file mode 100644 index 000000000..d1c961c95 --- /dev/null +++ b/src/migrations/2020_03_12_000000_add_parameters_to_minnesota_tax_income_information.php @@ -0,0 +1,17 @@ +minnesota_income_tax_information, function (Blueprint $table) { + $table->integer('additional_withholding')->default(0); + }); + } +} diff --git a/tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaIncomeTest.php b/tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaIncomeTest.php new file mode 100644 index 000000000..1fca545fc --- /dev/null +++ b/tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaIncomeTest.php @@ -0,0 +1,104 @@ +query_runner->addTax(self::TAX_CLASS); + + MinnesotaIncomeTaxInformation::createForUser([ + 'filing_status' => MinnesotaIncome::FILING_SINGLE, + 'allowances' => 0, + 'additional_withholding' => 0, + 'exempt' => false, + ], $this->user); + } + + /** + * @dataProvider provideTestData + */ + public function testTax(TestParameters $parameters): void + { + $this->validate($parameters); + } + + public function provideTestData(): array + { + $builder = new TestParametersBuilder(); + $builder + ->setDate(self::DATE) + ->setHomeLocation(self::LOCATION) + ->setTaxClass(self::TAX_CLASS) + ->setTaxInfoClass(self::TAX_INFO_CLASS) + ->setPayPeriods(52); + + return [ + '00' => [ + $builder + ->setTaxInfoOptions(['exempt' => true]) + ->setWagesInCents(30000) + ->setExpectedAmountInCents(0) + ->build() + ], + '01' => [ + $builder + ->setTaxInfoOptions(null) + ->setWagesInCents(30000) + ->setExpectedAmountInCents(1224) + ->build() + ], + '02' => [ + $builder + ->setTaxInfoOptions(['additional_withholding' => 20]) + ->setWagesInCents(30000) + ->setExpectedAmountInCents(3224) + ->build() + ], + '03' => [ + $builder + ->setTaxInfoOptions(['allowances' => 2]) + ->setWagesInCents(100000) + ->setExpectedAmountInCents(4465) + ->build() + ], + '04' => [ + $builder + ->setTaxInfoOptions(['allowances' => 2]) + ->setWagesInCents(200000) + ->setExpectedAmountInCents(11360) + ->build() + ], + '05' => [ + $builder + ->setTaxInfoOptions([ + 'filing_status' => MinnesotaIncome::FILING_MARRIED, + 'allowances' => 2, + ]) + ->setWagesInCents(100000) + ->setExpectedAmountInCents(3277) + ->build() + ], + '06' => [ + $builder + ->setTaxInfoOptions(['filing_status' => MinnesotaIncome::FILING_MARRIED]) + ->setWagesInCents(200000) + ->setExpectedAmountInCents(10995) + ->build() + ], + ]; + } +} diff --git a/tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaUnemploymentTest.php b/tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaUnemploymentTest.php new file mode 100644 index 000000000..c5e23e151 --- /dev/null +++ b/tests/Unit/Countries/US/Minnesota/V20200101/MinnesotaUnemploymentTest.php @@ -0,0 +1,61 @@ +query_runner->addTax(self::TAX_CLASS); + } + + /** + * @dataProvider provideData + */ + public function testWageBase(TestParameters $parameters): void + { + $this->validateWageBase($parameters); + } + + public function testWorkDifferentState(): void + { + $this->validateWorkDifferentState( + self::DATE, + self::LOCATION, + self::TAX_CLASS, + self::TAX_RATE + ); + } + + public function testTaxRate(): void + { + $this->validateTaxRate( + self::DATE, + self::LOCATION, + self::TAX_CLASS, + 0.0321 + ); + } + + public function provideData(): array + { + return $this->wageBaseBoundariesTestCases( + self::DATE, + self::LOCATION, + self::TAX_CLASS, + self::WAGE_BASE, + self::TAX_RATE + ); + } +}