diff --git a/changelog.d/8311.added.md b/changelog.d/8311.added.md new file mode 100644 index 00000000000..4f598d11466 --- /dev/null +++ b/changelog.d/8311.added.md @@ -0,0 +1 @@ +Added the South Carolina Homestead Exemption property tax reduction. diff --git a/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/age_threshold.yaml b/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/age_threshold.yaml new file mode 100644 index 00000000000..4ae027e4ed5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/age_threshold.yaml @@ -0,0 +1,12 @@ +description: South Carolina limits age-based eligibility to this threshold under the Homestead Exemption program. +values: + 2025-01-01: 65 +metadata: + unit: year + period: year + label: South Carolina homestead exemption age threshold + reference: + - title: South Carolina Department of Revenue | Exempt Property + href: https://dor.sc.gov/property/exempt-property + - title: South Carolina Code Section 12-37-250 + href: https://www.scstatehouse.gov/code/t12c037.php diff --git a/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/amount.yaml b/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/amount.yaml new file mode 100644 index 00000000000..9855929068f --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/amount.yaml @@ -0,0 +1,12 @@ +description: South Carolina provides this fair market value exemption amount under the Homestead Exemption program. +values: + 2025-01-01: 50_000 +metadata: + unit: currency-USD + period: year + label: South Carolina homestead exemption amount + reference: + - title: South Carolina Department of Revenue | Exempt Property + href: https://dor.sc.gov/property/exempt-property + - title: South Carolina Code Section 12-37-250 + href: https://www.scstatehouse.gov/code/t12c037.php diff --git a/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/assessment_rate.yaml b/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/assessment_rate.yaml new file mode 100644 index 00000000000..d0c8e4d90ee --- /dev/null +++ b/policyengine_us/parameters/gov/states/sc/tax/property/homestead_exemption/assessment_rate.yaml @@ -0,0 +1,12 @@ +description: South Carolina uses this share of fair market value as assessed value under the Homestead Exemption program. +values: + 2025-01-01: 0.04 +metadata: + unit: /1 + period: year + label: South Carolina homestead exemption legal residence assessment rate + reference: + - title: South Carolina Department of Revenue | Exempt Property + href: https://dor.sc.gov/property/exempt-property + - title: South Carolina Code Section 12-37-252 + href: https://www.scstatehouse.gov/code/t12c037.php diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption.yaml new file mode 100644 index 00000000000..cb8126eb086 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption.yaml @@ -0,0 +1,54 @@ +- name: Case 1, exemption is capped at the statutory amount. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_exemption: 2_000 + +- name: Case 2, exemption is limited to assessed property value. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 1_600 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_exemption: 1_600 + +- name: Case 3, exemption excludes non-joint adult property value. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 1_600 + person2: + age: 40 + assessed_property_value: 8_000 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: SINGLE + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_homestead_exemption: 1_600 diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption_eligible.yaml new file mode 100644 index 00000000000..0185d3fe47e --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption_eligible.yaml @@ -0,0 +1,129 @@ +- name: Case 1, senior homeowner is eligible. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_exemption_eligible: true + +- name: Case 2, disabled homeowner under age 65 is eligible. + period: 2025 + input: + people: + person1: + age: 40 + is_disabled: true + assessed_property_value: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_exemption_eligible: true + +- name: Case 3, blind homeowner under age 65 is eligible. + period: 2025 + input: + people: + person1: + age: 40 + is_blind: true + assessed_property_value: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_exemption_eligible: true + +- name: Case 4, non-senior homeowner without disability or blindness is ineligible. + period: 2025 + input: + people: + person1: + age: 64 + assessed_property_value: 8_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_exemption_eligible: false + +- name: Case 5, senior without assessed property is ineligible. + period: 2025 + input: + people: + person1: + age: 65 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_exemption_eligible: false + +- name: Case 6, joint spouse meeting the age test is eligible. + period: 2025 + input: + people: + person1: + age: 40 + assessed_property_value: 8_000 + is_tax_unit_head: true + person2: + age: 65 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person1, person2] + filing_status: JOINT + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_homestead_exemption_eligible: true + +- name: Case 7, non-joint adult meeting the age test is ineligible. + period: 2025 + input: + people: + person1: + age: 40 + assessed_property_value: 8_000 + is_tax_unit_head: true + person2: + age: 65 + is_tax_unit_spouse: true + tax_units: + tax_unit: + members: [person1, person2] + filing_status: SINGLE + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_homestead_exemption_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_property_tax_reduction.yaml b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_property_tax_reduction.yaml new file mode 100644 index 00000000000..2a4a8340aeb --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/sc/tax/property/homestead_exemption/sc_homestead_property_tax_reduction.yaml @@ -0,0 +1,76 @@ +- name: Case 1, reduction equals the property tax on the exempt share of value. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 8_000 + real_estate_taxes: 2_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_property_tax_reduction: 500 + +- name: Case 2, reduction cannot exceed property taxes. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 1_600 + real_estate_taxes: 800 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_property_tax_reduction: 800 + +- name: Case 3, ineligible filer gets no reduction. + period: 2025 + input: + people: + person1: + age: 64 + assessed_property_value: 8_000 + real_estate_taxes: 2_000 + tax_units: + tax_unit: + members: [person1] + households: + household: + members: [person1] + state_code: SC + output: + sc_homestead_property_tax_reduction: 0 + +- name: Case 4, reduction excludes non-joint adult property tax. + period: 2025 + input: + people: + person1: + age: 65 + assessed_property_value: 1_600 + real_estate_taxes: 800 + person2: + age: 40 + assessed_property_value: 8_000 + real_estate_taxes: 2_000 + tax_units: + tax_unit: + members: [person1, person2] + filing_status: SINGLE + households: + household: + members: [person1, person2] + state_code: SC + output: + sc_homestead_property_tax_reduction: 800 diff --git a/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption.py b/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption.py new file mode 100644 index 00000000000..e0b2dda4fb7 --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class sc_homestead_exemption(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina homestead exemption" + unit = USD + definition_period = YEAR + reference = "https://dor.sc.gov/property/exempt-property" + defined_for = "sc_homestead_exemption_eligible" + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.sc.tax.property.homestead_exemption + person = tax_unit.members + head = person("is_tax_unit_head", period) + joint_spouse = person("is_tax_unit_spouse", period) & person.tax_unit( + "tax_unit_is_joint", period + ) + assessed_value = tax_unit.sum( + person("assessed_property_value", period) * (head | joint_spouse) + ) + assessed_exemption_amount = p.amount * p.assessment_rate + return min_( + assessed_value, + assessed_exemption_amount, + ) diff --git a/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption_eligible.py b/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption_eligible.py new file mode 100644 index 00000000000..e10985332bb --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_exemption_eligible.py @@ -0,0 +1,27 @@ +from policyengine_us.model_api import * + + +class sc_homestead_exemption_eligible(Variable): + value_type = bool + entity = TaxUnit + label = "Eligible for the South Carolina Homestead Exemption" + definition_period = YEAR + reference = "https://dor.sc.gov/property/exempt-property" + defined_for = StateCode.SC + + def formula(tax_unit, period, parameters): + p = parameters(period).gov.states.sc.tax.property.homestead_exemption + person = tax_unit.members + head = person("is_tax_unit_head", period) + joint_spouse = person("is_tax_unit_spouse", period) & person.tax_unit( + "tax_unit_is_joint", period + ) + head_or_joint_spouse = head | joint_spouse + age = person("age", period.this_year) + is_disabled = person("is_disabled", period) + is_blind = person("is_blind", period) + assessed_value = person("assessed_property_value", period) + + return tax_unit.any( + ((age >= p.age_threshold) | is_disabled | is_blind) & head_or_joint_spouse, + ) & (tax_unit.sum(assessed_value * head_or_joint_spouse) > 0) diff --git a/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_property_tax_reduction.py b/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_property_tax_reduction.py new file mode 100644 index 00000000000..bce4dafd3ec --- /dev/null +++ b/policyengine_us/variables/gov/states/sc/tax/property/homestead_exemption/sc_homestead_property_tax_reduction.py @@ -0,0 +1,29 @@ +from policyengine_us.model_api import * + + +class sc_homestead_property_tax_reduction(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina homestead property tax reduction" + unit = USD + definition_period = YEAR + reference = "https://dor.sc.gov/property/exempt-property" + defined_for = "sc_homestead_exemption_eligible" + + def formula(tax_unit, period, parameters): + person = tax_unit.members + head = person("is_tax_unit_head", period) + joint_spouse = person("is_tax_unit_spouse", period) & person.tax_unit( + "tax_unit_is_joint", period + ) + head_or_joint_spouse = head | joint_spouse + assessed_value = tax_unit.sum( + person("assessed_property_value", period) * head_or_joint_spouse + ) + real_estate_taxes = tax_unit.sum( + person("real_estate_taxes", period) * head_or_joint_spouse + ) + + return real_estate_taxes * ( + tax_unit("sc_homestead_exemption", period) / max_(assessed_value, 1) + )