Skip to content

Commit

Permalink
Implement 2024/25 tax tables, simplify library usage (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
bennothommo authored Dec 9, 2024
1 parent 3c6b2b5 commit 8dd2c53
Show file tree
Hide file tree
Showing 59 changed files with 4,360 additions and 3,253 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ composer require manageitwa/payg-tax

This library is built to be able to be slotted in to most PHP software. The library publishes a number of interfaces within the `src/Entities` directory. At a bare minimum, you would need to fulfill the following interfaces:

- `Payer`: A payer record. The payer is generally the employer or the entity who is paying the payee.
- `Payer`: A payer record. The payer is the employer or the entity who is paying the payee.
- `Payee`: A payee record. The payee is the employee or entity who is being paid the gross income and needs income tax to be withheld from their earning.
- `Earning`: An earning record. The earning is a single gross amount of income that is paid either ad-hoc or as part of a pay cycle to the payee.

In general, you would like implement these interfaces into a model record for each of these entities.
In general, you would likely implement these interfaces into a model record for each of these entities.

```php
<?php
Expand Down
135 changes: 135 additions & 0 deletions src/Adjustments/July2024/MedicareLevyReduction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

declare(strict_types=1);

namespace ManageIt\PaygTax\Adjustments\July2024;

use ManageIt\PaygTax\Entities\Payer;
use ManageIt\PaygTax\Entities\Payee;
use ManageIt\PaygTax\Entities\Earning;
use ManageIt\PaygTax\Entities\TaxScale;
use ManageIt\PaygTax\Traits\WeeklyConversion;
use ManageIt\PaygTax\Utilities\Math;

class MedicareLevyReduction
{
use WeeklyConversion;

/**
* Whether the payee is claiming to have a spouse.
*/
public bool $spouse = true;

/**
* The number of children the payee is claiming for the Medicare Levy Reduction.
*/
public int $children = 0;

public function __construct(bool $spouse = true, int $children = 0)
{
$this->spouse = $spouse;
$this->children = $children;
}

public function getAdjustmentAmount(Payer $payer, Payee $payee, TaxScale $taxScale, Earning $earning): float
{
$weeklyGross = $this->getWeeklyGross(
$payee->getPayCycle(),
$earning->getGrossAmount(),
);

if ($payee->getMedicareLevyExemption() === Payee::MEDICARE_LEVY_EXEMPTION_NONE) {
// Weekly gross must be $500 or higher, but less than the shading out point
if ($weeklyGross < 500 || $weeklyGross >= $this->getShadingOutPoint($payee)) {
return 0;
}

if ($weeklyGross < 625) {
// Final value must be negative
return $this->convertWeeklyTax(
$payee->getPayCycle(),
Math::round(
($weeklyGross - 500)
* 0.1
)
) * -1;
} elseif ($weeklyGross >= 625 && $weeklyGross <= $this->getWeeklyFamilyThreshold()) {
// Final value must be negative
return $this->convertWeeklyTax(
$payee->getPayCycle(),
Math::round($weeklyGross * 0.02)
) * -1;
} else {
// Final value must be negative
return $this->convertWeeklyTax(
$payee->getPayCycle(),
Math::round(
($this->getWeeklyFamilyThreshold() * 0.02)
- (($weeklyGross - $this->getWeeklyFamilyThreshold()) * 0.08)
)
) * -1;
}
} elseif ($payee->getMedicareLevyExemption() === Payee::MEDICARE_LEVY_EXEMPTION_HALF) {
// Weekly gross must be $843 or higher, but less than the shading out point
if ($weeklyGross < 843 || $weeklyGross >= $this->getShadingOutPoint($payee)) {
return 0;
}

if ($weeklyGross < 1053) {
// Final value must be negative
return $this->convertWeeklyTax(
$payee->getPayCycle(),
Math::round(
($weeklyGross - 843.19)
* 0.05
)
) * -1;
} elseif ($weeklyGross >= 1053 && $weeklyGross <= $this->getWeeklyFamilyThreshold()) {
// Final value must be negative
return $this->convertWeeklyTax(
$payee->getPayCycle(),
Math::round($weeklyGross * 0.01)
) * -1;
} else {
// Final value must be negative
return $this->convertWeeklyTax(
$payee->getPayCycle(),
Math::round(
($this->getWeeklyFamilyThreshold() * 0.01)
- (($weeklyGross - $this->getWeeklyFamilyThreshold()) * 0.04)
)
) * -1;
}
}

return 0;
}

/**
* Calculate the weekly family threshold, where the reduction starts to apply.
*/
protected function getWeeklyFamilyThreshold(): float
{
if ($this->spouse === true && $this->children === 0) {
// $43,846 / 52 weeks
return 843.192307692;
}

// Up to a maximum of 10 children can be claimed
$children = min($this->children, 10);
$annualThreshold = 43846 + ($children * 4027);
return round($annualThreshold / 52, 2);
}

/**
* Calculate the shading out point where the reduction is no longer applicable.
*/
protected function getShadingOutPoint(Payee $payee): float
{
if ($payee->getMedicareLevyExemption() === Payee::MEDICARE_LEVY_EXEMPTION_NONE) {
return floor(($this->getWeeklyFamilyThreshold() * 0.1) / 0.08);
}

return floor(($this->getWeeklyFamilyThreshold() * 0.05) / 0.04);
}
}
83 changes: 83 additions & 0 deletions src/Adjustments/MedicareLevyReduction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace ManageIt\PaygTax\Adjustments;

use ManageIt\PaygTax\Entities\Payer;
use ManageIt\PaygTax\Entities\Payee;
use ManageIt\PaygTax\Entities\Earning;
use ManageIt\PaygTax\Entities\TaxAdjustment;
use ManageIt\PaygTax\Entities\TaxScale;
use ManageIt\PaygTax\Traits\WeeklyConversion;
use ManageIt\PaygTax\Utilities\Date;
use ManageIt\PaygTax\Utilities\Math;
use ManageIt\PaygTax\Adjustments;

class MedicareLevyReduction implements TaxAdjustment
{
use WeeklyConversion;

/**
* Whether the payee is claiming to have a spouse.
*/
public bool $spouse = true;

/**
* The number of children the payee is claiming for the Medicare Levy Reduction.
*/
public int $children = 0;

public function __construct(bool $spouse = true, int $children = 0)
{
$this->spouse = $spouse;
$this->children = $children;
}

public function isEligible(Payer $payer, Payee $payee, TaxScale $taxScale, Earning $earning): bool
{
// Not eligible if you do not have a TFN
if ($payee->hasTfnNumber() === false) {
return false;
}

// Not eligible if you're claiming a full Medicare levy exemption
if ($payee->getMedicareLevyExemption() === Payee::MEDICARE_LEVY_EXEMPTION_FULL) {
return false;
}

// Not eligible if you're not claiming the tax-free threshold
if ($payee->claimsTaxFreeThreshold() === false) {
return false;
}

// Not eligible if you're a foreign resident or Working Holiday Maker
if ($payee->getResidencyStatus() !== Payee::RESIDENT) {
return false;
}

// If claiming a half Medicare levy exemption (NAT 1004 Scale 6), the payee must be claiming children - the
// reduction is not applicable to payees who only have a spouse
if ($payee->getMedicareLevyExemption() === Payee::MEDICARE_LEVY_EXEMPTION_HALF && $this->children === 0) {
return false;
}

// The payee must be claiming to have a spouse or children
if ($this->spouse === false && $this->children === 0) {
return false;
}

return true;
}

public function getAdjustmentAmount(Payer $payer, Payee $payee, TaxScale $taxScale, Earning $earning): float
{
if (Date::from($earning->getPayDate(), '2024-07-01')) {
$adjustment = new Adjustments\July2024\MedicareLevyReduction($this->spouse, $this->children);
return $adjustment->getAdjustmentAmount($payer, $payee, $taxScale, $earning);
}

$adjustment = new Adjustments\October2020\MedicareLevyReduction($this->spouse, $this->children);
return $adjustment->getAdjustmentAmount($payer, $payee, $taxScale, $earning);
}
}
33 changes: 3 additions & 30 deletions src/Adjustments/October2020/MedicareLevyReduction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@
use ManageIt\PaygTax\Entities\Payer;
use ManageIt\PaygTax\Entities\Payee;
use ManageIt\PaygTax\Entities\Earning;
use ManageIt\PaygTax\Entities\TaxAdjustment;
use ManageIt\PaygTax\Entities\TaxScale;
use ManageIt\PaygTax\TaxScales\October2020\Nat1004Scale2;
use ManageIt\PaygTax\TaxScales\October2020\Nat1004Scale6;
use ManageIt\PaygTax\Traits\WeeklyConversion;
use ManageIt\PaygTax\Utilities\Math;

class MedicareLevyReduction implements TaxAdjustment
class MedicareLevyReduction
{
use WeeklyConversion;

Expand All @@ -34,38 +31,14 @@ public function __construct(bool $spouse = true, int $children = 0)
$this->children = $children;
}

public function isEligible(Payer $payer, Payee $payee, TaxScale $taxScale, Earning $earning): bool
{
// The tax scale must be either of the following tax scales
if (
$taxScale instanceof Nat1004Scale2 === false
&& $taxScale instanceof Nat1004Scale6 === false
) {
return false;
}

// The payee must be claiming to have a spouse or children
if ($this->spouse === false && $this->children === 0) {
return false;
}

// If claiming a half Medicare levy exemption (NAT 1004 Scale 6), the payee must be claiming children - the
// reduction is not applicable to payees who only have a spouse
if ($taxScale instanceof Nat1004Scale6 && $this->children === 0) {
return false;
}

return true;
}

public function getAdjustmentAmount(Payer $payer, Payee $payee, TaxScale $taxScale, Earning $earning): float
{
$weeklyGross = $this->getWeeklyGross(
$payee->getPayCycle(),
$earning->getGrossAmount(),
);

if ($taxScale instanceof Nat1004Scale2) {
if ($payee->getMedicareLevyExemption() === Payee::MEDICARE_LEVY_EXEMPTION_NONE) {
// Weekly gross must be $438 or higher, but less than the shading out point
if ($weeklyGross < 438 || $weeklyGross >= $this->getShadingOutPoint()) {
return 0;
Expand Down Expand Up @@ -96,7 +69,7 @@ public function getAdjustmentAmount(Payer $payer, Payee $payee, TaxScale $taxSca
)
) * -1;
}
} elseif ($taxScale instanceof Nat1004Scale6) {
} elseif ($payee->getMedicareLevyExemption() === Payee::MEDICARE_LEVY_EXEMPTION_HALF) {
// Weekly gross must be $739 or higher, but less than the shading out point
if ($weeklyGross < 739 || $weeklyGross >= $this->getShadingOutPoint()) {
return 0;
Expand Down
Loading

0 comments on commit 8dd2c53

Please sign in to comment.