diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 5a4e8dab3..04ad01da1 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -14,7 +14,7 @@ jobs: with: persist-credentials: false - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install package diff --git a/.github/workflows/check_format.yml b/.github/workflows/check_format.yml index a261c2597..410c82124 100644 --- a/.github/workflows/check_format.yml +++ b/.github/workflows/check_format.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 - uses: psf/black@stable with: options: "-l 79 --check" diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 9d0be7420..44aa6eb3b 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -15,10 +15,10 @@ jobs: - name: Setup Miniconda uses: conda-incubator/setup-miniconda@v2 with: - miniforge-variant: Mambaforge + miniconda-version: "latest" activate-environment: fiscalsim-us-dev environment-file: environment.yml - python-version: "3.10" + python-version: "3.11" auto-activate-base: false - name: Install package and build documentation shell: bash -l {0} diff --git a/.github/workflows/docs_check.yml b/.github/workflows/docs_check.yml index fa344ba82..4fc68ddc4 100644 --- a/.github/workflows/docs_check.yml +++ b/.github/workflows/docs_check.yml @@ -12,7 +12,7 @@ jobs: - name: Setup Miniconda uses: conda-incubator/setup-miniconda@v2 with: - miniforge-variant: Mambaforge + miniconda-version: "latest" activate-environment: fiscalsim-us-dev environment-file: environment.yml python-version: "3.11" diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish_to_pypi.yml index dbfce66cc..6b237d2df 100644 --- a/.github/workflows/publish_to_pypi.yml +++ b/.github/workflows/publish_to_pypi.yml @@ -14,9 +14,9 @@ jobs: - name: Checkout repo uses: actions/checkout@v4 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Build package run: make pip-package - name: Publish a Python distribution to PyPI diff --git a/CHANGELOG.md b/CHANGELOG.md index 39b17b239..7626d556a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2024-10-03 02:00:00 + +### Added + +- Updates South Carolina tax logic and tests +- Replaces Mambaforge Python installer with Miniforge in GH Actions + ## [0.2.9] - 2024-04-11 00:30:00 ### Added @@ -211,6 +218,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - First prototype version based off of openfisca-us and tax-calculator. +[0.3.0]: https://github.com/TheCGO/fiscalsim-us/compare/v0.2.9...v0.3.0 [0.2.9]: https://github.com/TheCGO/fiscalsim-us/compare/v0.2.8...v0.2.9 [0.2.8]: https://github.com/TheCGO/fiscalsim-us/compare/v0.2.7...v0.2.8 [0.2.7]: https://github.com/TheCGO/fiscalsim-us/compare/v0.2.6...v0.2.7 diff --git a/changelog.yaml b/changelog.yaml index a26af9284..994f2c43f 100644 --- a/changelog.yaml +++ b/changelog.yaml @@ -191,3 +191,9 @@ - Limits `docs_check.yml` to only run on pull request commits. - Updates some tags in `README.md.` date: 2024-04-11 00:30:00 +- bump: minor + changes: + added: + - Updates South Carolina tax logic and tests. + - Replaces Mambaforge Python installer with Miniforge in GH Actions + date: 2024-10-03 02:00:00 diff --git a/environment.yml b/environment.yml index 7edf0354e..b7795a767 100644 --- a/environment.yml +++ b/environment.yml @@ -1,4 +1,13 @@ name: fiscalsim-us-dev +channels: +- conda-forge dependencies: - python>=3.10,<3.12 + - sphinx>=3.5.4 + - sphinx-argparse + - sphinxcontrib-bibtex>=2.0.0 + - sphinx-math-dollar + - pydata-sphinx-theme + - jupyter-book>=0.11.3 + - jupyter - pip diff --git a/fiscalsim_us/data/datasets/README.md b/fiscalsim_us/data/datasets/README.md index 1f7aab7a9..49a529f70 100644 --- a/fiscalsim_us/data/datasets/README.md +++ b/fiscalsim_us/data/datasets/README.md @@ -5,7 +5,7 @@ If you are updating the microdata (e.g., modifying code in `cps.py`), you will n Steps: 1. Clear old microdata with `rm fiscalsim_us/data/storage/*.h5` 2. Generate new microdata in Python with a command like this: `python -c "from fiscalsim_us.data import CPS_2023; CPS_2023().generate()"` -3. Make a copy of the new microdata file with a name that includes the _bumped_ version number. For example, if FiscalSim US is currently version 0.1.0 and you are updating the 2023 CPS in a minor-bump PR, run `cp fiscalsim_us/data/storage/cps_2023.h5 fiscalsim_us/data/storage/cps_2023_v0_263_5.h5`. +3. Make a copy of the new microdata file with a name that includes the _bumped_ version number. For example, if FiscalSim-US is currently version 0.2.9 and you are updating the 2023 CPS in a minor-bump PR, run `cp fiscalsim_us/data/storage/cps_2023.h5 fiscalsim_us/data/storage/cps_2023_v0_263_5.h5`. 4. Upload this new file to [github.com/TheCGO/fiscalsim-us/releases](https://github.com/TheCGO/fiscalsim-us/releases), both overwriting the existing unversioned file (delete the old one) and adding the versioned file as a new release. -5. Update the `CPS_2023` class in `fiscalsim_us/data/cps.py` to point to the new versioned file, e.g. `new_url="release://TheCGO/fiscalsim-us/cps-2023/cps_2023_v0_263_5.h5",`. +5. Update the `CPS_2023` class in `fiscalsim_us/data/cps.py` to point to the new versioned file, e.g. `new_url="release://TheCGO/fiscalsim-us/v0.2.9/cps_2023_v0_2_9.h5",`. 6. Verify that this works by downloading it, e.g. `python -c "from fiscalsim_us.data import CPS_2023; CPS_2023().download()"`. diff --git a/fiscalsim_us/data/datasets/cps/cps.py b/fiscalsim_us/data/datasets/cps/cps.py index 4573bcdb1..2510f0b57 100644 --- a/fiscalsim_us/data/datasets/cps/cps.py +++ b/fiscalsim_us/data/datasets/cps/cps.py @@ -57,7 +57,7 @@ def add_silver_plan_cost(self, cps: h5py.File, year: int): cps (h5py.File): The CPS dataset file. year (int): The year of the data. """ - from policyengine_us import Microsimulation + from fiscalsim_us import Microsimulation sim = Microsimulation(dataset=self) slspc = sim.calc("second_lowest_silver_plan_cost", year).values @@ -374,5 +374,5 @@ class CPS_2022(CPS): "cps_2023", "CPS 2023", STORAGE_FOLDER / "cps_2023.h5", - new_url="release://policyengine/policyengine-us/cps-2023/cps_2023.h5", + new_url="release://TheCGO/fiscalsim-us/v0.2.9/cps_2023.h5", ) diff --git a/fiscalsim_us/data/datasets/cps/enhanced_cps/enhanced_cps.py b/fiscalsim_us/data/datasets/cps/enhanced_cps/enhanced_cps.py index b984eb420..ace7c59a9 100644 --- a/fiscalsim_us/data/datasets/cps/enhanced_cps/enhanced_cps.py +++ b/fiscalsim_us/data/datasets/cps/enhanced_cps/enhanced_cps.py @@ -8,9 +8,7 @@ class EnhancedCPS_2023(Dataset): file_path = STORAGE_FOLDER / "enhanced_cps.h5" data_format = Dataset.ARRAYS time_period = "2023" - url = ( - "release://policyengine/fiscalsim-us/enhanced-cps-2023/enhanced_cps.h5" - ) + url = "release://policyengine/policyengine-us/enhanced-cps-2023/enhanced_cps.h5" def generate(self): from .puf_extended_cps import PUFExtendedCPS_2023 diff --git a/fiscalsim_us/data/datasets/cps/raw_cps.py b/fiscalsim_us/data/datasets/cps/raw_cps.py index 9e5ad7fa6..084e6f978 100644 --- a/fiscalsim_us/data/datasets/cps/raw_cps.py +++ b/fiscalsim_us/data/datasets/cps/raw_cps.py @@ -155,9 +155,10 @@ def generate(self) -> pd.DataFrame: "Received a 404 response when fetching the data." ) try: - with BytesIO() as file, pd.HDFStore( - self.file_path, mode="w" - ) as storage: + with ( + BytesIO() as file, + pd.HDFStore(self.file_path, mode="w") as storage, + ): content_length_actual = 0 for data in response.iter_content(int(1e6)): progress_bar.update(len(data)) diff --git a/fiscalsim_us/parameters/gov/states/sc/README.md b/fiscalsim_us/parameters/gov/states/sc/README.md index 885a35897..73ba607c8 100644 --- a/fiscalsim_us/parameters/gov/states/sc/README.md +++ b/fiscalsim_us/parameters/gov/states/sc/README.md @@ -1 +1,7 @@ # South Carolina +We do not model the following components of the South Carolina SC1040 2023 Individual Income Tax Return +- line 19, Nonresident sale of real estate (paid on form I-290) +- All credits under line 22 + - line 22a, Anhydrous Ammonia (form I-333) + - line 22b, Milk credit (form I-334) + - line 22c, Classroom Teacher Expenses (form I-360) diff --git a/fiscalsim_us/parameters/gov/states/sc/index.yaml b/fiscalsim_us/parameters/gov/states/sc/index.yaml deleted file mode 100644 index 2852e302a..000000000 --- a/fiscalsim_us/parameters/gov/states/sc/index.yaml +++ /dev/null @@ -1,4 +0,0 @@ -metadata: - propagate_metadata_to_children: true - economy: false - household: false diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/additions/additions.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/additions/additions.yaml new file mode 100644 index 000000000..9e49ed4fc --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/additions/additions.yaml @@ -0,0 +1,24 @@ +description: South Carolina adds these sources from federal taxable income to determine state taxable income. +values: + 2021-01-01: + - sc_state_tax_addback + # - Out-of-state losses + # - Expenses related to National Guard and Military Reserve Income + # - Interest income on obligations of states and political subdivisions other than South Carolina + # - Other additions to income + +metadata: + unit: list + period: year + label: South Carolina federal taxable income additions + reference: + - title: SC 1040 tax form (2021) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf#page=2 + - title: SC 1040 tax form instructions (2021) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=13 + - title: SC Legal Code | SECTION 12-6-1110 + href: https://www.scstatehouse.gov/code/t12c006.php + - title: SC 1040 tax form (2022) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=20 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/max_amount_pchild.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/max_amount_pchild.yaml new file mode 100644 index 000000000..c85b4c25a --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/max_amount_pchild.yaml @@ -0,0 +1,11 @@ +description: South Carolina child and dependent care credit maximum amount per child +metadata: + unit: currency-USD + name: sc_cdcc_amount_pchld + label: South Carolina child and dependent care credit maximum amount per child + period: year + reference: + - title: Form SC1040 intructions, line 11, Child and Dependent Care Credit + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page32 +values: + 2020-01-01: 210 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/max_care_expense_year_offset.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/max_care_expense_year_offset.yaml index 90dd249e0..9555b9a7b 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/max_care_expense_year_offset.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/max_care_expense_year_offset.yaml @@ -11,6 +11,8 @@ metadata: href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=22 - title: South Carolina Legal Code | SECTION 12-6-3380 href: https://www.scstatehouse.gov/code/t12c006.php + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=32 unit: int period: year label: Decoupled year offset for maximum CDCC expense cap diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/rate.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/rate.yaml index 407c1637e..3bafb9385 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/rate.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/rate.yaml @@ -1,15 +1,17 @@ description: South Carolina matches this share of the federal Child and Dependent Care Credit. -values: +values: 2020-01-01: 0.07 metadata: unit: /1 period: year label: South Carolina Child and Dependent Care Credit match - reference: + reference: - title: SC-1040 2020 href: https://dor.sc.gov/forms-site/Forms/SC1040_2020.pdf - - title: Instructions for Form SC-1040 (line 11) + - title: Instructions for Form SC-1040, 2020 (line 11) href: https://dor.sc.gov/forms-site/Forms/IITPacket_2020.pdf#page=20 + - title: Instructions for Form SC-1040, 2023 (line 11) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=32 - title: South Carolina Legal Code | SECTION 12-6-3380 href: https://www.scstatehouse.gov/code/t12c006.php diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/total_max.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/total_max.yaml new file mode 100644 index 000000000..4cc487989 --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/cdcc/total_max.yaml @@ -0,0 +1,11 @@ +description: Maximum South Carolina child and dependent care total match +metadata: + unit: currency-USD + name: sc_cdcc_max_total_expense + label: Maximum care CDCC expenses total match + period: year + reference: + - title: Form SC1040 intructions, line 11, Child and Dependent Care Credit + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page32 +values: + 2020-01-01: 420 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/eitc/rate.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/eitc/rate.yaml index 4ed2aceaf..1c6227d2a 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/eitc/rate.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/eitc/rate.yaml @@ -14,6 +14,8 @@ metadata: href: https://dor.sc.gov/forms-site/Forms/TC60_2021.pdf - title: South Carolina Schedule TC-60 2022 (2022) href: https://dor.sc.gov/forms-site/Forms/TC60_2022.pdf + - title: South Carolina Schedule TC-60 2023 (2023) + href: https://dor.sc.gov/forms-site/Forms/TC60_2023.pdf#page=1 - title: South Carolina Code of Laws Section 12-6-3632 href: https://www.scstatehouse.gov/code/t12c006.php diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/non_refundable.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/non_refundable.yaml new file mode 100644 index 000000000..9541e4f89 --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/non_refundable.yaml @@ -0,0 +1,18 @@ +description: South Carolina non-refundable tax credits. +values: + 2021-01-01: + - sc_cdcc + - sc_eitc + - sc_two_wage_earner_credit +metadata: + unit: list + label: South Carolina non-refundable tax credits + reference: + - title: SC 1040 tax form (2021) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf + - title: SC 1040 tax form instructions (2021) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=22 + - title: SC 1040 tax form (2022) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=3 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=44 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/refundable.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/refundable.yaml new file mode 100644 index 000000000..619e29f69 --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/refundable.yaml @@ -0,0 +1,17 @@ +description: South Carolina refundable tax credits. +values: + 2021-01-01: + - sc_tuition_credit + - sc_parentrefund_credit +metadata: + unit: list + label: South Carolina refundable tax credits + reference: + - title: SC 1040 tax form (2021) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf#page=3 + - title: SC 1040 tax form instructions (2021) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=23 + - title: SC 1040 tax form (2022) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=3 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=44 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/earned_income.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/earned_income.yaml deleted file mode 100644 index 117499598..000000000 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/earned_income.yaml +++ /dev/null @@ -1,23 +0,0 @@ -description: South Carolina counts these income sources as earned income for the two wage earner credit. -values: - 2021-01-01: - - employment_income - # - commisions - # - sub_pay - - self_employment_income - - qualified_business_income - - partnership_s_corp_income - - farm_income - -metadata: - unit: list - reference: - - title: SC 1040 tax form (2021) - href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf - - title: SC 1040 tax form instructions (2021) - href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=22 - - title: SC Legal Code | Section 12-6-3330 (C) - href: https://www.scstatehouse.gov/code/t12c006.php - - title: SC 1040 tax form (2022) - href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf - diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/earned_income/subtractions.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/earned_income/subtractions.yaml new file mode 100644 index 000000000..7c0c1dd9c --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/earned_income/subtractions.yaml @@ -0,0 +1,18 @@ +description: South Carolina subtracts the following elements from gross earned income when computing the two wage earner credit. +values: + 2021-01-01: + - self_employment_tax_ald_person + - self_employed_health_insurance_ald_person + - self_employed_pension_contribution_ald_person + +metadata: + unit: list + period: year + label: South Carolina two wage earner credit earned income subtractions + reference: + - title: SC 1040 tax form instructions (2021) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=22 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=23 + - title: SC Legal Code | Section 12-6-3330 (C)(b) + href: https://www.scstatehouse.gov/code/t12c006.php diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/rate.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/rate.yaml index 54a2a350b..9fd2b368a 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/rate.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/credits/two_wage_earner/rate.yaml @@ -8,6 +8,7 @@ brackets: - threshold: 2021-01-01: 43_333 2022-01-01: 46_667 + 2023-01-01: 50_000 rate: 2021-01-01: 0 @@ -17,6 +18,8 @@ metadata: href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=23 - title: SC 1040 tax form instructions (2022) href: https://dor.sc.gov/forms-site/Forms/IITPacket_2022.pdf#page=23 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=32 - title: SC Legal Code | Section 12-6-3330 (B) # Legal code set it to $50,000, then amended it to $30,000 in 2017. # Now adjusted for inflation. diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/net_capital_gain/rate.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/net_capital_gain/rate.yaml index 2454e03bb..fc2f35387 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/net_capital_gain/rate.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/net_capital_gain/rate.yaml @@ -15,3 +15,5 @@ metadata: href: https://www.scstatehouse.gov/code/t12c006.php - title: SC1040 tax form (2022) href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=23 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/young_child/amount.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/young_child/amount.yaml new file mode 100644 index 000000000..b4518b124 --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/young_child/amount.yaml @@ -0,0 +1,21 @@ +description: South Carolina provides a young child deduction of this amount. +values: + 2019-01-01: 4_100 # Value in the legal code, last updated in 2019. + 2021-01-01: 4_300 + 2022-01-01: 4_430 + 2023-01-01: 4_610 + +metadata: + unit: currency-USD + period: year + label: South Carolina young child deduction amount + reference: + - title: SC 1040 tax form instructions (2021) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=19 + # 12-6-1160 defines the program and points to the amount in 1140. + - title: SC Legal Code | SECTION 12-6-1160 + href: https://www.scstatehouse.gov/code/t12c006.php + - title: SC 1040 tax form (2022) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=29 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/young_child/ineligible_age.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/young_child/ineligible_age.yaml new file mode 100644 index 000000000..caf68add7 --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/deductions/young_child/ineligible_age.yaml @@ -0,0 +1,18 @@ +description: South Carolina limits its young child deduction to children below this age. +values: + 2021-01-01: 6 +metadata: + unit: year + period: year + label: South Carolina young child deduction ineligible age + reference: + - title: SC 1040 tax form (2021) Line t + href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf#page=2 + - title: SC 1040 tax form instructions (2021) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=19 + - title: SC Legal Code | SECTION 12-6-1160 + href: https://www.scstatehouse.gov/code/t12c006.php + - title: SC 1040 tax form (2022) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=19 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/age_threshold.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/age_threshold.yaml index 86b32f523..b5e2c7c66 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/age_threshold.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/age_threshold.yaml @@ -7,5 +7,7 @@ metadata: href: https://www.scstatehouse.gov/code/t12c006.php - title: Instructions for Form SC-1040 (line 3q) href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=19 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=27 values: 2021-01-01: 65 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/amount.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/amount.yaml index 4dc5bf523..4597bda88 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/amount.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/amount.yaml @@ -7,5 +7,7 @@ metadata: href: https://www.scstatehouse.gov/code/t12c006.php - title: Instructions for Form SC-1040 (line 3q) href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=19 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=27 values: 2021-01-01: 15_000 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/spouse_amount.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/spouse_amount.yaml index ddc5ff42d..47b3c2545 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/spouse_amount.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/senior/spouse_amount.yaml @@ -7,5 +7,7 @@ metadata: href: https://www.scstatehouse.gov/code/t12c006.php - title: Instructions for Form SC-1040 (line 3q) href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=19 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=27 values: 2021-01-01: 15_000 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/young_child/amount.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/young_child/amount.yaml deleted file mode 100644 index 73d206b0a..000000000 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/young_child/amount.yaml +++ /dev/null @@ -1,13 +0,0 @@ -description: South Carolina provides a young child exemption of this amount. -values: - 2022-01-01: 4_430 - -metadata: - unit: currency-USD - period: year - label: South Carolina young child tax credit amount - reference: - - title: 2022 INDIVIDUAL INCOME TAX RETURN SC1040 - href: https://dor.sc.gov/forms-site/Forms/IITPacket_2022.pdf - - title: 2022 SC1040 INDIVIDUAL INCOME TAX FORM AND INSTRUCTIONS - href: https://dor.sc.gov/forms-site/Forms/IITPacket_2022.pdf diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/young_child/ineligible_age.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/young_child/ineligible_age.yaml deleted file mode 100644 index 24d498d22..000000000 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/exemptions/young_child/ineligible_age.yaml +++ /dev/null @@ -1,10 +0,0 @@ -description: South Carolina limits its young child exemption to children below this age. -values: - 2022-01-01: 6 -metadata: - reference: - - title: South Carolina Section 12-6-1140 - href: https://www.scstatehouse.gov/code/t12c006.php - unit: year - period: year - label: South Carolina young child tax credit ineligible age diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/rates.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/rates.yaml index 54c0da316..923627f3b 100644 --- a/fiscalsim_us/parameters/gov/states/sc/tax/income/rates.yaml +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/rates.yaml @@ -1,30 +1,71 @@ -description: The tax rates for individual residents in South Carolina. -# threshold value is bottom of the tax bracket; thresholds are <= -brackets: - - threshold: - 2022-01-01: 0 - rate: - 2022-01-01: 0.00 - - threshold: - 2022-01-01: 3_200 - rate: - 2022-01-01: 0.03 - - threshold: - 2022-01-01: 16_040 - rate: - 2022-01-01: 0.065 - - -metadata: - reference: - - title: SC 2022 Income Tax Chart - href: https://dor.sc.gov/forms-site/Forms/SC1040TT_2022.pdf - - title: SC 2021 Income Tax Chart - href: https://dor.sc.gov/forms-site/Forms/SC1040TT_2021.pdf - - title: SC Legal Code | Section 12-6-510 - href: https://www.scstatehouse.gov/code/t12c006.php - label: SC Resident Individual Tax Rates - type: marginal_rate - threshold_unit: currency-USD - rate_unit: /1 - period: year +description: South Carolina taxes the income of individuals at this rate. +brackets: + - threshold: + 1994-01-01: 0 + rate: + 1994-01-01: 0.025 + 2021-01-01: 0 + - threshold: + 1994-01-01: 2_220 + 2021-01-01: 3_110 + 2022-01-01: 3_200 + 2023-01-01: 3_330 + 2024-01-01: 3_460 + rate: + 1994-01-01: 0.03 + - threshold: + 1994-01-01: 4_440 + 2021-01-01: 6_220 + 2022-01-01: 16_040 + 2023-01-01: 16_680 + 2024-01-01: 17_330 + rate: + 1994-01-01: 0.04 + 2022-01-01: 0.065 + 2023-01-01: 0.064 + 2024-01-01: 0.062 + - threshold: + 1994-01-01: 6_660 + 2021-01-01: 9_330 + 2022-01-01: .inf + rate: + 1994-01-01: 0.05 + - threshold: + 1994-01-01: 8_880 + 2021-01-01: 12_440 + 2022-01-01: .inf + rate: + 1994-01-01: 0.06 + - threshold: + 1994-01-01: 11_100 + 2021-01-01: 15_560 + 2022-01-01: .inf + rate: + 1994-01-01: 0.07 + 2022-01-01: 0.065 + - threshold: + 1994-01-01: .inf + + + +metadata: + reference: + - title: What is South Carona Individual Income Tax? + href: https://dor.sc.gov/tax/individual-income + - title: SC 1040ES Instructions 2023 + href: https://dor.sc.gov/forms-site/Forms/SC1040ES_2023.pdf#page=4 + - title: SC 2022 Income Tax Chart + href: https://dor.sc.gov/forms-site/Forms/SC1040TT_2022.pdf + - title: SC 2021 Income Tax Chart + href: https://dor.sc.gov/forms-site/Forms/SC1040TT_2021.pdf + - title: SC Legal Code | Section 12-6-510 + href: https://www.scstatehouse.gov/code/t12c006.php + # Using a third party source as South Carolina does not provide inflation + # adjustments for the tax brackets + - title: South Carolina Tax Rates, Brackets, Forms + href: https://www.efile.com/south-carolina-tax-rates-brackets-and-forms/ + label: South Carolina income tax rate + type: marginal_rate + threshold_unit: currency-USD + rate_unit: /1 + period: year diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/retirement/cap.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/retirement/cap.yaml new file mode 100644 index 000000000..4871ee1ef --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/retirement/cap.yaml @@ -0,0 +1,33 @@ +description: South Carolina caps the retirement deduction at this amount, based on age. + +metadata: + threshold_unit: year + amount_unit: currency_USD + type: single_amount + reference: + - title: South Carolina State SECTION 12-6-1170(B) + href: https://www.scstatehouse.gov/code/t12c006.php + - title: South Carolina State SECTION 12-6-1170(A)(1) + href: https://www.scstatehouse.gov/code/t12c006.php + - title: South Carolina State SECTION 12-6-1170(A)(1) + href: https://www.scstatehouse.gov/code/t12c006.php + - title: Instructions for Form SC-1040 (line 3p) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=16 + - title: SC-1040 2021 + href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf#page=2 + - title: SC-1040 2022 + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=25 + period: year + label: South Carolina retirement deduction cap + +brackets: + - threshold: + 2021-01-01: 0 + amount: + 2021-01-01: 3_000 + - threshold: + 2021-01-01: 65 + amount: + 2021-01-01: 10_000 diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/retirement/subtract_military.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/retirement/subtract_military.yaml new file mode 100644 index 000000000..a5403f984 --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/retirement/subtract_military.yaml @@ -0,0 +1,23 @@ +description: South Carolina subtracts the survivors retirement deduction from the military retirement deduction if this is true. +metadata: + unit: bool + label: South Carolina choice to subtract survivors retirement deduction from military retirement deduction + reference: + - title: Instructions for Form SC-1040 (line 3p) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=17 + - title: Instructions for Form SC-1040 (line 3p) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2022.pdf#page=19 + - title: SC-1040 2021 + href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf#page=2 + - title: SC-1040 2022 + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2 + # The law indicates the 2022 case. We model calculation of the survivors retirement deduction in 2021 based on the tax form, + # where the retirement deduction is subtracts from military retirement deduction. + - title: South Carolina State SECTION 12-6-1170(C)(1) + href: https://www.scstatehouse.gov/code/t12c006.php + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=25 + +values: + 2021-01-01: true + 2022-01-01: false diff --git a/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/subtractions.yaml b/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/subtractions.yaml new file mode 100644 index 000000000..6a52ef9bc --- /dev/null +++ b/fiscalsim_us/parameters/gov/states/sc/tax/income/subtractions/subtractions.yaml @@ -0,0 +1,40 @@ +description: South Carolina subtracts these sources from federal taxable income to determine state taxable income. +values: + 2021-01-01: + - salt_refund_income + - disability_benefits #include tax disability benefits + - sc_net_capital_gain_deduction + - investment_in_529_plan + - us_govt_interest + - taxable_social_security + - sc_military_deduction + - sc_retirement_deduction + - sc_senior_exemption + - sc_young_child_deduction + - sc_dependent_exemption + # - Out of state income/gain + # - Volunteer deductions + # - Active Trade or Business Income deduction + # - Certain nontaxable National Guard or Reserve pay + # - Negative amount of federal taxable income + # - Subsistence allowance + # - Consumer Protection Services + # - Other subtractions + +metadata: + unit: list + period: year + label: South Carolina federal taxable income subtractions + reference: + - title: SC 1040 tax form (2021) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2021.pdf#page=2 + - title: SC 1040 tax form instructions (2021) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=14 + - title: SC Legal Code | SECTION 12-6-1130 + href: https://www.scstatehouse.gov/code/t12c006.php + - title: SC Legal Code | SECTION 12-6-1140 + href: https://www.scstatehouse.gov/code/t12c006.php + - title: SC 1040 tax form (2022) + href: https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2 + - title: SC 1040 tax form instructions (2023) + href: https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=43 diff --git a/fiscalsim_us/tests/microsimulation/test_microsim.py b/fiscalsim_us/tests/microsimulation/test_microsim.py index 3ce5c857a..3864df336 100644 --- a/fiscalsim_us/tests/microsimulation/test_microsim.py +++ b/fiscalsim_us/tests/microsimulation/test_microsim.py @@ -1,3 +1,7 @@ +import pytest + + +@pytest.mark.skipif(True, reason="This test temporarily suspended.") def test_microsim_runs_cps(): import numpy as np from fiscalsim_us import Microsimulation diff --git a/fiscalsim_us/tests/policy/baseline/gov/irs/integration/qbid.yaml b/fiscalsim_us/tests/policy/baseline/gov/irs/integration/qbid.yaml index 13b21ade9..37690569c 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/irs/integration/qbid.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/irs/integration/qbid.yaml @@ -100,9 +100,9 @@ income_tax: 23_409.82 # ----------------------------------------------------------------------------- -# BEGIN : PolicyEngineUS test cases derived from TPC publication test cases +# BEGIN : FiscalSim-US test cases derived from TPC publication test cases # -# Test PolicyEngineUS QBID calculations using the six tax units specified in +# Test FiscalSim-US QBID calculations using the six tax units specified in # Table 1 of this TPC publication: "Navigating the New Pass-Through Provisions: # A Technical Explanation" by William G. Gale and Aaron Krupkin # (January 31, 2018), which is available at this URL: @@ -297,5 +297,5 @@ output: qualified_business_income_deduction: 10_000 -# END : PolicyEngineUS test cases derived from TPC publication test cases +# END : FiscalSim-US test cases derived from TPC publication test cases # ----------------------------------------------------------------------------- diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/ca/tax/income/credits/earned_income/ca_eitc.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/ca/tax/income/credits/earned_income/ca_eitc.yaml index 65011c8a0..9c127e087 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/states/ca/tax/income/credits/earned_income/ca_eitc.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/states/ca/tax/income/credits/earned_income/ca_eitc.yaml @@ -49,7 +49,7 @@ earned_income_tax_credit: 0 # too much investment income to be eligible income_tax: -9648 # expected CA results: - ca_income_tax_before_credits: 164.14 # this is a PolicyEngineUS output + ca_income_tax_before_credits: 164.14 # this is a FiscalSimUS output ca_exemptions: 1_058 # treated as a nonrefundable credit ca_income_tax_before_refundable_credits: 0 ca_eitc: 0 # too much investment income to be CalEITC eligible diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/additions/sc_additions.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/additions/sc_additions.yaml new file mode 100644 index 000000000..a4d34e95e --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/additions/sc_additions.yaml @@ -0,0 +1,12 @@ +- name: Test case 1 # SALT has a cap of 5000 for seperate + period: 2021 + input: + filing_status: SEPARATE + tax_unit_itemizes: true + medical_expense_deduction: 6_000 # Goes into itemized_taxable_income_deductions + standard_deduction: 4_000 + real_estate_taxes: 3_000 + prior_year_state_income_tax_paid: 1_000 + state_code: SC + output: + sc_additions: 1_000 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_state_tax_addback.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/additions/sc_state_tax_addback.yaml similarity index 52% rename from fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_state_tax_addback.yaml rename to fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/additions/sc_state_tax_addback.yaml index 42ec6a7ba..9057c3e0a 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_state_tax_addback.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/additions/sc_state_tax_addback.yaml @@ -1,38 +1,35 @@ -- name: Test case 1 #salt has a cap of 5000 for seperate +- name: Test case 1 # SALT has a cap of 5000 for seperate period: 2021 input: filing_status: SEPARATE tax_unit_itemizes: true - charitable_deduction: 1_000 - interest_deduction: 1_000 - medical_expense_deduction: 0 - casualty_loss_deduction: 0 + medical_expense_deduction: 6_000 # Goes into itemized_taxable_income_deductions standard_deduction: 4_000 real_estate_taxes: 3_000 - statelocal_sales_or_prior_inctax: 1_000 + prior_year_state_income_tax_paid: 1_000 state_code: SC output: sc_state_tax_addback: 1_000 - # line 3 = 2000 - 0 = 2000 + # line 1 = 6000 + # line 2 = 0 + # line 3 = 6000 - 0 = 6000 # line 4 = 1000 # line 5 = 5000 - 3000 = 2000 + # line 6 = min(6000, 1000, 2000) = 1000 - name: Test case 2 #salt has a cap of 10000 for JOINT period: 2021 input: filing_status: JOINT tax_unit_itemizes: true - charitable_deduction: 1_000 - interest_deduction: 1_000 - medical_expense_deduction: 0 - casualty_loss_deduction: 0 + medical_expense_deduction: 6_000 # Goes into itemized_taxable_income_deductions standard_deduction: 4_000 real_estate_taxes: 3_000 statelocal_sales_or_prior_inctax: 1_000 state_code: SC output: - sc_state_tax_addback: 0 - # line 3 = 2000 - 4000 = 0 + sc_state_tax_addback: 1_000 + # line 3 = 6000 - 4000 = 2000 # line 4 = 1000 # line 5 = 10000 - 3000 = 7000 @@ -41,17 +38,14 @@ input: filing_status: JOINT tax_unit_itemizes: true - charitable_deduction: 3_000 - interest_deduction: 1_000 - medical_expense_deduction: 0 - casualty_loss_deduction: 0 + medical_expense_deduction: 14_000 # Goes into itemized_taxable_income_deductions standard_deduction: 1_000 real_estate_taxes: 8_000 statelocal_sales_or_prior_inctax: 6_000 state_code: SC output: sc_state_tax_addback: 2_000 - # line 3 = 4000 - 1000 = 3000 + # line 3 = 14000 - 1000 = 13000 # line 4 = 6000 # line 5 = 10000 - 8000 = 2000 @@ -60,35 +54,42 @@ input: filing_status: JOINT tax_unit_itemizes: true - charitable_deduction: 1_000 - interest_deduction: 1_000 - medical_expense_deduction: 0 - casualty_loss_deduction: 0 + medical_expense_deduction: 6_000 # Goes into itemized_taxable_income_deductions standard_deduction: 4_000 real_estate_taxes: 3_000 statelocal_sales_or_prior_inctax: 1_000 state_code: SC + output: + sc_state_tax_addback: 1_000 + # line 3 = 6000 - 4000 = 2000 + # line 4 = 1000 + # line 5 = 10000 - 3000 = 7000 + +- name: Test case 5 # if federal standard deduction > itemized deductoins + period: 2021 + input: + filing_status: JOINT + tax_unit_itemizes: true + itemized_taxable_income_deductions: 6_000 + standard_deduction: 8_000 + real_estate_taxes: 3_000 + statelocal_sales_or_prior_inctax: 1_000 + state_code: SC output: sc_state_tax_addback: 0 - # line 3 = 2000 - 4000 = 0 + # line 3 = max(0, 6000 - 8000) = 0 # line 4 = 1000 # line 5 = 10000 - 3000 = 7000 -- name: Test case 5 #salt has a cap of 10000 for JOINT +- name: Test case 6 # not eligible for federal itemized deductoins period: 2021 input: filing_status: JOINT tax_unit_itemizes: false - charitable_deduction: 3_000 - interest_deduction: 1_000 - medical_expense_deduction: 0 - casualty_loss_deduction: 0 - standard_deduction: 1_000 - real_estate_taxes: 8_000 - statelocal_sales_or_prior_inctax: 6_000 + itemized_taxable_income_deductions: 6_000 + standard_deduction: 2_000 + real_estate_taxes: 3_000 + statelocal_sales_or_prior_inctax: 1_000 state_code: SC output: sc_state_tax_addback: 0 - # line 3 = 0 - 1000 = 0 tax_unit_itemizes false - # line 4 = 6000 - # line 5 = 10000 - 8000 = 2000 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/sc_cdcc.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/cdcc/sc_cdcc.yaml similarity index 100% rename from fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/sc_cdcc.yaml rename to fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/cdcc/sc_cdcc.yaml diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit_eligible.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit_eligible.yaml new file mode 100644 index 000000000..65df70e78 --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit_eligible.yaml @@ -0,0 +1,12 @@ +- name: Basic calculation, not eligible + period: 2022 + input: + people: + person1: + is_tax_unit_head: true + households: + household: + members: [person1] + state_code: TX + output: + sc_tuition_credit_eligible: false diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/eitc/sc_eitc.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/eitc/sc_eitc.yaml index fb25073fe..49a4f323c 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/eitc/sc_eitc.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/eitc/sc_eitc.yaml @@ -1,7 +1,7 @@ - name: No EITC from federal in 2021 period: 2021 input: - earned_income_tax_credit: 0 + eitc: 0 state_code: SC output: sc_eitc: 0 @@ -9,7 +9,7 @@ - name: In 2018, with $1,000 EITC period: 2018 input: - earned_income_tax_credit: 1_000 + eitc: 1_000 state_code: SC output: sc_eitc: 208.3 @@ -17,7 +17,7 @@ - name: In 2019, with $1,000 EITC period: 2019 input: - earned_income_tax_credit: 1_000 + eitc: 1_000 state_code: SC output: sc_eitc: 416.7 @@ -25,7 +25,7 @@ - name: In 2020, with $1,000 EITC period: 2020 input: - earned_income_tax_credit: 1_000 + eitc: 1_000 state_code: SC output: sc_eitc: 625 @@ -33,7 +33,7 @@ - name: In 2021, with $1,000 EITC period: 2021 input: - earned_income_tax_credit: 1_000 + eitc: 1_000 state_code: SC output: sc_eitc: 833.3 @@ -41,7 +41,7 @@ - name: In 2022, with $1,000 EITC period: 2022 input: - earned_income_tax_credit: 1_000 + eitc: 1_000 state_code: SC output: sc_eitc: 1041.7 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/two_wage_earner/integration.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/two_wage_earner/integration.yaml new file mode 100644 index 000000000..dca4bf5d3 --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/two_wage_earner/integration.yaml @@ -0,0 +1,54 @@ +- name: Tax unit with taxsimid 7811 in j21.its.csv and j21.ots.csv + absolute_error_margin: 0.01 + period: 2021 + input: + people: + person1: + age: 28 + qualified_dividend_income: 2_005 + taxable_interest_income: 5_505 + short_term_capital_gains: 4_005 + long_term_capital_gains: 1_005 + rental_income: 3_005 + rent: 24_000 + self_employment_income: 21_010 + business_is_qualified: true + business_is_sstb: true + w2_wages_from_qualified_business: 100e6 + ssi: 0 # not in TAXSIM35 + state_supplement: 0 # not in TAXSIM35 + wic: 0 # not in TAXSIM35 + person2: + age: 28 + employment_income: 108_010 + qualified_dividend_income: 2_005 + taxable_interest_income: 5_505 + short_term_capital_gains: 4_005 + long_term_capital_gains: 1_005 + rental_income: 3_005 + ssi: 0 # not in TAXSIM35 + state_supplement: 0 # not in TAXSIM35 + wic: 0 # not in TAXSIM35 + person3: + age: 11 + ssi: 0 # not in TAXSIM35 + state_supplement: 0 # not in TAXSIM35 + wic: 0 # not in TAXSIM35 + tax_units: + tax_unit: + members: [person1, person2, person3] + premium_tax_credit: 0 # not in TAXSIM35 + local_income_tax: 0 # not in TAXSIM35 + state_sales_tax: 0 # not in TAXSIM35 + spm_units: + spm_unit: + members: [person1, person2, person3] + snap: 0 # not in TAXSIM35 + tanf: 0 # not in TAXSIM35 + households: + household: + members: [person1, person2, person3] + state_fips: 45 # SC + output: # expected results from patched TAXSIM35 2024-01-11 version + sc_two_wage_earner_credit: 136.68 + sc_income_tax: 8_042.25 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/two_wage_earner/sc_gross_earned_income.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/two_wage_earner/sc_gross_earned_income.yaml new file mode 100644 index 000000000..e79889e8d --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/credits/two_wage_earner/sc_gross_earned_income.yaml @@ -0,0 +1,25 @@ +- name: Basic calculation + period: 2022 + input: + earned_income: 2_800 + state_code: SC + output: + sc_gross_earned_income: 2_800 + +- name: With subtractions, capped at 0 + period: 2022 + input: + earned_income: 2_800 + self_employment_tax_ald_person: 3_000 + state_code: SC + output: + sc_gross_earned_income: 0 + +- name: With subtractions, capped at 0 + period: 2022 + input: + earned_income: 2_800 + self_employment_tax_ald_person: 500 + state_code: SC + output: + sc_gross_earned_income: 2_300 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/net_captial_gain/sc_net_capital_gain_deduction.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/net_captial_gain/sc_net_capital_gain_deduction.yaml index 2055cb32f..d2906f413 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/net_captial_gain/sc_net_capital_gain_deduction.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/net_captial_gain/sc_net_capital_gain_deduction.yaml @@ -1,7 +1,35 @@ -- name: Case 1, capital_gains is positive +- name: Base is positive, stcg are positive period: 2021 input: state_code: SC - net_capital_gain: 1_000 + long_term_capital_gains: 900 + short_term_capital_gains: 100 output: - sc_net_capital_gain_deduction: 440 + sc_net_capital_gain_deduction: 396 + +- name: Bse is positive, stcg are positive + period: 2021 + input: + state_code: SC + long_term_capital_gains: 900 + short_term_capital_gains: -100 + output: + sc_net_capital_gain_deduction: 352 + +- name: Base is negative + period: 2021 + input: + state_code: SC + long_term_capital_gains: 600 + short_term_capital_gains: -700 + output: + sc_net_capital_gain_deduction: 0 + +- name: Base is negative + period: 2021 + input: + state_code: SC + long_term_capital_gains: 7_000 + short_term_capital_gains: -5_000 + output: + sc_net_capital_gain_deduction: 880 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_young_child.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/sc_young_child_deduction.yaml similarity index 87% rename from fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_young_child.yaml rename to fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/sc_young_child_deduction.yaml index 4bb8cf980..ed5d67cd6 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_young_child.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/deductions/sc_young_child_deduction.yaml @@ -1,37 +1,37 @@ -- name: 1 child under 6 gets $4,430 young child exemption. - period: 2022 - input: - people: - parent: {} - child: - age: 5 - tax_units: - tax_unit: - members: [parent, child] - households: - household: - members: [parent, child] - state_code: SC - output: - sc_young_child_exemption: 4_430 - -- name: Family with a child age 6 and two children age 4 gets two young child exemptions. - period: 2022 - input: - people: - parent: {} - child1: - age: 4 - child2: - age: 4 - child3: - age: 6 - tax_units: - tax_unit: - members: [parent, child1, child2, child3] - households: - household: - members: [parent, child1, child2, child3] - state_code: SC - output: - sc_young_child_exemption: 8_860 +- name: 1 child under 6 gets $4,430 young child exemption. + period: 2022 + input: + people: + parent: {} + child: + age: 5 + tax_units: + tax_unit: + members: [parent, child] + households: + household: + members: [parent, child] + state_code: SC + output: + sc_young_child_deduction: 4_430 + +- name: Family with a child age 6 and two children age 4 gets two young child exemptions. + period: 2022 + input: + people: + parent: {} + child1: + age: 4 + child2: + age: 4 + child3: + age: 6 + tax_units: + tax_unit: + members: [parent, child1, child2, child3] + households: + household: + members: [parent, child1, child2, child3] + state_code: SC + output: + sc_young_child_deduction: 8_860 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/integration.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/integration.yaml new file mode 100644 index 000000000..85a4dfddb --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/integration.yaml @@ -0,0 +1,41 @@ +- name: Tax unit with taxsimid 13715 in f21.its.csv and f21.ots.csv + absolute_error_margin: 0.01 + period: 2021 + input: + people: + person1: + age: 67 + employment_income: 27_010 + taxable_interest_income: 5_505 + taxable_private_pension_income: 6_000 + social_security_retirement: 11_500 + ssi: 0 # not in TAXSIM35 + state_supplement: 0 # not in TAXSIM35 + wic: 0 # not in TAXSIM35 + person2: + age: 67 + employment_income: 30_010 + taxable_interest_income: 5_505 + taxable_private_pension_income: 6_000 + social_security_retirement: 11_500 + ssi: 0 # not in TAXSIM35 + state_supplement: 0 # not in TAXSIM35 + wic: 0 # not in TAXSIM35 + tax_units: + tax_unit: + members: [person1, person2] + premium_tax_credit: 0 # not in TAXSIM35 + local_income_tax: 0 # not in TAXSIM35 + state_sales_tax: 0 # not in TAXSIM35 + spm_units: + spm_unit: + members: [person1, person2] + snap: 0 # not in TAXSIM35 + tanf: 0 # not in TAXSIM35 + households: + household: + members: [person1, person2] + state_fips: 45 # SC + output: # expected results from patched TAXSIM35 2023-12-07 version + sc_retirement_deduction: 12_000 + sc_senior_exemption: 30_000 - 12_000 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.yaml new file mode 100644 index 000000000..f86514da3 --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.yaml @@ -0,0 +1,15 @@ +- name: Case 1, 1 dependent, get 1 dependent exemptions. + period: 2022 + input: + state_code: SC + tax_unit_dependents: 1 + output: + sc_dependent_exemption: 4_430 + +- name: Case 2, family with 3 dependents, get 3 dependent exemptions. + period: 2022 + input: + state_code: SC + tax_unit_dependents: 3 + output: + sc_dependent_exemption: 13_290 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_senior_exemption.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_senior_exemption.yaml index 14a717402..67aff9e43 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_senior_exemption.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/exemptions/sc_senior_exemption.yaml @@ -3,83 +3,58 @@ absolute_error_margin: 0 input: state_code: SC - filing_status: JOINT - age_head: 65 - age_spouse: 65 - sc_retirement_income_deduction_head: 0 - sc_retirement_income_deduction_spouse: 2_000 - sc_military_retirement_income_deduction_head: 0 - sc_military_retirement_income_deduction_spouse: 0 + age: 65 + sc_retirement_deduction_indv: 0 + sc_military_deduction_indv: 2_000 + is_tax_unit_head_or_spouse: true output: - # (15,000 - 0 - 0) + (15,000 - 2_000 - 0) = 28,000 - sc_senior_exemption: 28_000 + # (15,000 - 2_000 - 0) = 13,000 + sc_senior_exemption_person: 13_000 -- name: If filing jointly, only one person is age 65 or above +- name: Age ineligible period: 2022 absolute_error_margin: 0 input: state_code: SC - filing_status: JOINT - age_head: 65 - age_spouse: 64 - sc_retirement_income_deduction_head: 5_000 - sc_retirement_income_deduction_spouse: 2_000 - sc_military_retirement_income_deduction_head: 0 - sc_military_retirement_income_deduction_spouse: 0 + age: 64 + sc_retirement_deduction_indv: 0 + sc_military_deduction_indv: 2_000 + is_tax_unit_head_or_spouse: true output: - # 1*15,000 - 5,000 = 10,000 - sc_senior_exemption: 10_000 + sc_senior_exemption_person: 0 - -- name: If filing jointly, head and spouse both under age 65, exemption is $0. +- name: Not head or spouse so ineligible period: 2022 absolute_error_margin: 0 input: state_code: SC - filing_status: JOINT - age_head: 64 - age_spouse: 64 - sc_retirement_income_deduction_head: 5_000 - sc_retirement_income_deduction_spouse: 0 - sc_military_retirement_income_deduction_head: 0 - sc_military_retirement_income_deduction_spouse: 0 + age: 65 + sc_retirement_deduction_indv: 0 + sc_military_deduction_indv: 2_000 + is_tax_unit_head_or_spouse: false output: - sc_senior_exemption: 0 + sc_senior_exemption_person: 0 -- name: If filing seperately, head and spouse are both above 65 +- name: Fully reduced period: 2022 absolute_error_margin: 0 input: state_code: SC - filing_status: SEPARATE - age_head: 65 - age_spouse: 65 - sc_retirement_income_deduction_head: 5_000 - sc_retirement_income_deduction_spouse: 0 - sc_military_retirement_income_deduction_head: 0 - sc_military_retirement_income_deduction_spouse: 0 + age: 65 + sc_retirement_deduction_indv: 15_000 + sc_military_deduction_indv: 2_000 + is_tax_unit_head_or_spouse: true output: - # 15,000 - 5,000 - 0 = 10,000 - sc_senior_exemption: 10_000 + sc_senior_exemption_person: 0 -- name: If filing seperately, head and spouse are both above 65, but the retirement income ducion plus military retrement income deduction is greater than $15,000 +- name: No reduction period: 2022 absolute_error_margin: 0 input: state_code: SC - filing_status: SEPARATE - age_head: 65 - age_spouse: 65 - sc_retirement_income_deduction_head: 8_000 - sc_retirement_income_deduction_spouse: 2_000 - sc_military_retirement_income_deduction_head: 7_500 - sc_military_retirement_income_deduction_spouse: 0 + age: 65 + sc_retirement_deduction_indv: 0 + sc_military_deduction_indv: 0 + is_tax_unit_head_or_spouse: true output: - # 15,000 - 8,000 - 7,500 < 0 - sc_senior_exemption: 0 - - - - - - + sc_senior_exemption_person: 15_000 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_credits.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_non_refundable_credits.yaml similarity index 50% rename from fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_credits.yaml rename to fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_non_refundable_credits.yaml index 68aa4eb9c..817ae31c5 100644 --- a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_credits.yaml +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_non_refundable_credits.yaml @@ -1,34 +1,54 @@ -- name: income in 1st tax bracket - period: 2022 - absolute_error_margin: 1 - input: - sc_taxable_income: 2_800 - state_code: SC - output: - # no tax before 3_200 - sc_income_tax_before_credits: 0 - -- name: income in 2nd tax bracket - period: 2022 - absolute_error_margin: 1 - input: - sc_taxable_income: 12_000 - state_code: SC - output: - # 12_000*0.03 - 96 - # $96 is mechanically determined by the rate structure - # $3,200 * 3% = $96 - sc_income_tax_before_credits: 264 - -- name: income in 3rd tax bracket - period: 2022 - absolute_error_margin: 1 - input: - sc_taxable_income: 20_800 - state_code: SC - output: - # 20_800*0.065 - 658 = 694 - # $694 is mechanically determined by the rate structure - # 6.5% * $20,800-(0% * $3,200 + (3% * ($16,040 - $3,200)) + 6.5% * ($20,800 - $16,040)) - # $96 + 6.5% * ($16,040 - $3,200) = $96 + 6.5% * $12,840 = $96 + $834 - sc_income_tax_before_credits: 694 +- name: income in 1st tax bracket + period: 2022 + absolute_error_margin: 1 + input: + sc_taxable_income: 2_800 + state_code: SC + output: + # no tax before 3_200 + sc_income_tax_before_non_refundable_credits: 0 + +- name: income in 2nd tax bracket + period: 2022 + absolute_error_margin: 1 + input: + sc_taxable_income: 12_100 + state_code: SC + output: + # Result confirmed with the SC Tax Table + # 12_100*0.03 - 96 + # $96 is mechanically determined by the rate structure + # $3,200 * 3% = $96 + sc_income_tax_before_non_refundable_credits: 266 + +- name: income in 3rd tax bracket + period: 2022 + absolute_error_margin: 1 + input: + sc_taxable_income: 20_800 + state_code: SC + output: + # Result confirmed with the SC Tax Table + # 20_800*0.065 - 658 = 694 + # $694 is mechanically determined by the rate structure + # 6.5% * $20,800-(0% * $3,200 + (3% * ($16,040 - $3,200)) + 6.5% * ($20,800 - $16,040)) + # $96 + 6.5% * ($16,040 - $3,200) = $96 + 6.5% * $12,840 = $96 + $834 + sc_income_tax_before_non_refundable_credits: 694 + +- name: 2021 test for the 3rd bracket + period: 2021 + input: + sc_taxable_income: 6_800 + state_code: SC + output: + # Result confirmed with the SC Tax Table + sc_income_tax_before_non_refundable_credits: 116.5 + +- name: 2021 test for the highest income tax bracket + period: 2021 + input: + sc_taxable_income: 16_200 + state_code: SC + output: + # Result confirmed with the SC Tax Table + sc_income_tax_before_non_refundable_credits: 605.2 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_refundable_credits.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_refundable_credits.yaml new file mode 100644 index 000000000..94631a339 --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_income_tax_before_refundable_credits.yaml @@ -0,0 +1,17 @@ +- name: Reduction + period: 2022 + input: + sc_non_refundable_credits: 2_800 + state_code: SC + sc_income_tax_before_non_refundable_credits: 3_000 + output: + sc_income_tax_before_refundable_credits: 200 + +- name: Capped at 0 + period: 2022 + input: + sc_non_refundable_credits: 2_800 + state_code: SC + sc_income_tax_before_non_refundable_credits: 2_700 + output: + sc_income_tax_before_refundable_credits: 0 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_taxable_income.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_taxable_income.yaml new file mode 100644 index 000000000..a27fd91a7 --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_taxable_income.yaml @@ -0,0 +1,19 @@ +- name: Taxable income is capped at 0 + period: 2022 + input: + taxable_income: 800 + state_code: SC + sc_additions: 100 + sc_subtractions: 1_000 + output: + sc_taxable_income: 0 + +- name: Calculation + period: 2022 + input: + taxable_income: 2_800 + state_code: SC + sc_additions: 900 + sc_subtractions: 1_000 + output: + sc_taxable_income: 2_700 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_withheld_income_tax.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_withheld_income_tax.yaml new file mode 100644 index 000000000..1af64eed2 --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/sc_withheld_income_tax.yaml @@ -0,0 +1,29 @@ +- name: Person with income over the standard deduction amount + period: 2022 + absolute_error_margin: 0.01 + input: + adjusted_gross_income_person: 17_000 + filing_status: JOINT + state_code: SC + output: + sc_withheld_income_tax: 25.5 + +- name: Changing the filing status should not change the output + period: 2022 + absolute_error_margin: 0.01 + input: + adjusted_gross_income_person: 17_000 + filing_status: SURVIVING_SPOUSE + state_code: SC + output: + sc_withheld_income_tax: 25.5 + +- name: Capped at 0 + period: 2022 + absolute_error_margin: 0.01 + input: + adjusted_gross_income_person: 12_000 + filing_status: SURVIVING_SPOUSE + state_code: SC + output: + sc_withheld_income_tax: 0 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_indv.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_indv.yaml new file mode 100644 index 000000000..ec271795a --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_indv.yaml @@ -0,0 +1,17 @@ +- name: Case 1, indiviaul is head or spouse with military retirement pay of $4,000. + period: 2022 + input: + military_retirement_pay: 4_000 + is_tax_unit_head_or_spouse: true + state_code: SC + output: + sc_military_deduction_indv: 4_000 + +- name: Case 2, indiviaul is neither head nor spouse with military retirement pay of $5,000. + period: 2022 + input: + military_retirement_pay: 5_000 + is_tax_unit_head_or_spouse: false + state_code: SC + output: + sc_military_deduction_indv: 0 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_survivors.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_survivors.yaml new file mode 100644 index 000000000..37af1071e --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_survivors.yaml @@ -0,0 +1,7 @@ +- name: Case 1, one deceased spouse + period: 2022 + input: + military_retirement_pay_survivors: 11_000 + state_code: SC + output: + sc_military_deduction_survivors: 11_000 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_cap.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_cap.yaml new file mode 100644 index 000000000..8900e18cd --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_cap.yaml @@ -0,0 +1,23 @@ +- name: Case 1, above age threshold. + period: 2022 + input: + age: 70 + state_code: SC + output: + sc_retirement_cap: 10_000 + +- name: Case 2, below age threshold. + period: 2022 + input: + age: 64 + state_code: SC + output: + sc_retirement_cap: 3_000 + +- name: Case 3, at age threshold. + period: 2022 + input: + age: 65 + state_code: SC + output: + sc_retirement_cap: 10_000 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_indv.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_indv.yaml new file mode 100644 index 000000000..e75b0bc3a --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_indv.yaml @@ -0,0 +1,43 @@ +- name: Case 1, above age threshold, military retirement deduction higher than cap. + period: 2022 + input: + taxable_pension_income: 1_000 + military_retirement_pay: 11_000 + age: 70 + is_tax_unit_head_or_spouse: true + state_code: SC + output: + sc_retirement_deduction_indv: 0 + +- name: Case 2, below age threshold, military retirement deduction higher than cap. + period: 2022 + input: + taxable_pension_income: 1_000 + military_retirement_pay: 4_000 + age: 64 + is_tax_unit_head_or_spouse: true + state_code: SC + output: + sc_retirement_deduction_indv: 0 + +- name: Case 3, above age threshold, military retirement deduction lower than cap. + period: 2022 + input: + taxable_pension_income: 7_000 + military_retirement_pay: 6_000 + age: 70 + is_tax_unit_head_or_spouse: true + state_code: SC + output: + sc_retirement_deduction_indv: 4_000 + +- name: Case 4, below age threshold, military retirement deduction lower than cap. + period: 2022 + input: + taxable_pension_income: 500 + military_retirement_pay: 2_000 + age: 64 + is_tax_unit_head_or_spouse: true + state_code: SC + output: + sc_retirement_deduction_indv: 500 diff --git a/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.yaml b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.yaml new file mode 100644 index 000000000..f862eac24 --- /dev/null +++ b/fiscalsim_us/tests/policy/baseline/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.yaml @@ -0,0 +1,39 @@ +- name: Case 1, in 2022, above age threshold + period: 2022 + input: + pension_survivors: 1_000 + military_retirement_pay_survivors: 4_000 + age: 70 + state_code: SC + output: + sc_retirement_deduction_survivors: 1_000 + +- name: Case 2, in 2022, below age threshold + period: 2022 + input: + pension_survivors: 4_000 + military_retirement_pay_survivors: 6_000 + age: 64 + state_code: SC + output: + sc_retirement_deduction_survivors: 3_000 + +- name: Case 3, in 2021, above age threshold + period: 2021 + input: + pension_survivors: 2_000 + military_retirement_pay_survivors: 4_000 + age: 70 + state_code: SC + output: + sc_retirement_deduction_survivors: 2_000 + +- name: Case 4, in 2021, below age threshold + period: 2021 + input: + pension_survivors: 4_000 + military_retirement_pay_survivors: 6_000 + age: 64 + state_code: SC + output: + sc_retirement_deduction_survivors: 0 diff --git a/fiscalsim_us/tests/policy/contrib/taxsim/misc/eitc_2021_childless.yaml b/fiscalsim_us/tests/policy/contrib/taxsim/misc/eitc_2021_childless.yaml index 761dfe90f..0e5e69615 100644 --- a/fiscalsim_us/tests/policy/contrib/taxsim/misc/eitc_2021_childless.yaml +++ b/fiscalsim_us/tests/policy/contrib/taxsim/misc/eitc_2021_childless.yaml @@ -1,4 +1,4 @@ -# PolicyEngine-US test file derived from p21.its.csv and p21.ots.csv files +# FiscalSim-US test file derived from p21.its.csv and p21.ots.csv files # Expected test output from NBER TAXSIM Model v35 (06/18/22) With TCJA - name: Tax unit with taxsimid 998 from p21.its.csv diff --git a/fiscalsim_us/variables/gov/hud/hud_income_level.py b/fiscalsim_us/variables/gov/hud/hud_income_level.py index 7c692c861..ef3753fb6 100644 --- a/fiscalsim_us/variables/gov/hud/hud_income_level.py +++ b/fiscalsim_us/variables/gov/hud/hud_income_level.py @@ -27,7 +27,7 @@ def formula(spm_unit, period, parameters): ami = spm_unit("ami", period) # avoid array divide-by-zero warning by not using where() function # see following GitHub issue for more details: - # https://github.com/PolicyEngine/fiscalsim-us/issues/2496 + # https://github.com/PolicyEngine/policyengine-us/issues/2496 income_ami_ratio = np.zeros_like(ami) mask = ami != 0 income_ami_ratio[mask] = annual_income[mask] / ami[mask] diff --git a/fiscalsim_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_parent/ssi_unearned_income_deemed_from_ineligible_parent.py b/fiscalsim_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_parent/ssi_unearned_income_deemed_from_ineligible_parent.py index b357f9d06..aa6643b82 100644 --- a/fiscalsim_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_parent/ssi_unearned_income_deemed_from_ineligible_parent.py +++ b/fiscalsim_us/variables/gov/ssa/ssi/eligibility/income/deemed/from_ineligible_parent/ssi_unearned_income_deemed_from_ineligible_parent.py @@ -57,7 +57,7 @@ def formula(person, period, parameters): count_eligible_children = tax_unit.sum(eligible_child) # avoid array divide-by-zero warnings by not using where() function # see the following GitHub issue for more details: - # https://github.com/PolicyEngine/fiscalsim-us/issues/2494 + # https://github.com/PolicyEngine/policyengine-us/issues/2494 income = np.zeros_like(count_eligible_children) mask = count_eligible_children > 0 income[mask] = ( diff --git a/fiscalsim_us/variables/gov/states/co/tax/income/co_non_refundable_credits.py b/fiscalsim_us/variables/gov/states/co/tax/income/co_non_refundable_credits.py index 6c372fdc0..f3fdbc6a8 100644 --- a/fiscalsim_us/variables/gov/states/co/tax/income/co_non_refundable_credits.py +++ b/fiscalsim_us/variables/gov/states/co/tax/income/co_non_refundable_credits.py @@ -10,4 +10,4 @@ class co_non_refundable_credits(Variable): defined_for = StateCode.CO -# Colorado non refundable credits currently not modeled in PolicyEngine +# Colorado non refundable credits currently not modeled in FiscalSim diff --git a/fiscalsim_us/variables/gov/states/nc/tax/income/deductions/nc_itemized_deductions.py b/fiscalsim_us/variables/gov/states/nc/tax/income/deductions/nc_itemized_deductions.py index 7b5a21c35..93dcb82fe 100644 --- a/fiscalsim_us/variables/gov/states/nc/tax/income/deductions/nc_itemized_deductions.py +++ b/fiscalsim_us/variables/gov/states/nc/tax/income/deductions/nc_itemized_deductions.py @@ -29,7 +29,8 @@ def formula(tax_unit, period, parameters): mortgage_interest + property_taxes, pco.mortgage_and_property_tax ) - # North Carolina specifies a state and local tax deduction cap which is currently not modeled in PolicyEngine + # North Carolina specifies a state and local tax deduction cap which is + # currently not modeled in FiscalSim other_deductions = add( tax_unit, diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/additions/sc_additions.py b/fiscalsim_us/variables/gov/states/sc/tax/income/additions/sc_additions.py new file mode 100644 index 000000000..ec0a03130 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/additions/sc_additions.py @@ -0,0 +1,11 @@ +from fiscalsim_us.model_api import * + + +class sc_additions(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina additions" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + adds = "gov.states.sc.tax.income.additions.additions" diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_state_tax_addback.py b/fiscalsim_us/variables/gov/states/sc/tax/income/additions/sc_state_tax_addback.py similarity index 100% rename from fiscalsim_us/variables/gov/states/sc/tax/income/sc_state_tax_addback.py rename to fiscalsim_us/variables/gov/states/sc/tax/income/additions/sc_state_tax_addback.py diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/cdcc/sc_cdcc.py b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/cdcc/sc_cdcc.py index 4f612dda0..74a41d319 100644 --- a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/cdcc/sc_cdcc.py +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/cdcc/sc_cdcc.py @@ -2,6 +2,10 @@ class sc_cdcc(Variable): + """ + South Carolina Child and Dependent Care Credit, line 11 on form SC1040 + """ + value_type = float entity = TaxUnit label = "South Carolina CDCC" @@ -9,7 +13,7 @@ class sc_cdcc(Variable): unit = USD definition_period = YEAR reference = ( - "https://dor.sc.gov/forms-site/Forms/IITPacket_2022.pdf#page=22" + "https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=32" ) defined_for = StateCode.SC @@ -18,14 +22,6 @@ def formula(tax_unit, period, parameters): p_sc = parameters(period).gov.states.sc.tax.income.credits.cdcc p_us = parameters(period).gov.irs.credits.cdcc - # Year 2021 is different from federal cdcc - max_decoupled_year_offset = p_sc.max_care_expense_year_offset - period_max = period.offset(max_decoupled_year_offset) - sc_max_care_expense = parameters(period_max).gov.irs.credits.cdcc.max - - # Get child care expenses. - childcare_expenses = tax_unit("tax_unit_childcare_expenses", period) - # Married filing separate are ineligible. filing_status = tax_unit("filing_status", period) eligible = filing_status != filing_status.possible_values.SEPARATE @@ -34,9 +30,34 @@ def formula(tax_unit, period, parameters): count_cdcc_eligible = min_( tax_unit("count_cdcc_eligible", period), p_us.eligibility.max ) + # Calculate the total state CDCC match for years starting before 2023 + pre_2023 = period.start.year < 2023 + + # Year 2021 is different from federal cdcc + max_decoupled_year_offset = p_sc.max_care_expense_year_offset + period_max = period.offset(max_decoupled_year_offset) + sc_max_care_expense = parameters(period_max).gov.irs.credits.cdcc.max + + # Get child care expenses. + childcare_expenses = tax_unit("tax_unit_childcare_expenses", period) + # Maximum value cannot exceed cap # Calculate total CDCC capped_expenses = min_( childcare_expenses, sc_max_care_expense * count_cdcc_eligible ) - return eligible * capped_expenses * p_sc.rate + sc_pre2023_tot_cdcc_match = eligible * capped_expenses * p_sc.rate + + # Calculate the total state CDCC match for years starting on or after + # 2023 + max_expense = min_( + p_sc.max_amount_pchild * count_cdcc_eligible, p_sc.total_max + ) + sc_post2023_tot_cdcc_match = min_( + max_expense, p_sc.rate * tax_unit("cdcc", period) + ) + sc_tot_cdcc_match = ( + pre_2023 * sc_pre2023_tot_cdcc_match + + (not pre_2023) * sc_post2023_tot_cdcc_match + ) + return sc_tot_cdcc_match diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_parentrefund_credit.py b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_parentrefund_credit.py new file mode 100644 index 000000000..bcffdb8c7 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_parentrefund_credit.py @@ -0,0 +1,16 @@ +from fiscalsim_us.model_api import * + + +class sc_parentrefund_credit(Variable): + """ + Parental refund credit, refundable credit, line 22d on SC1040 2023 + Invidual Income Tax Return (see form I-361) + """ + + value_type = float + entity = Person + label = "South Carolina Parent Refund Credit" + defined_for = "sc_tuition_credit_eligible" + unit = USD + definition_period = YEAR + reference = ("https://dor.sc.gov/forms-site/Forms/I361_2023.pdf",) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit.py b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit.py new file mode 100644 index 000000000..37b27d84a --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit.py @@ -0,0 +1,21 @@ +from fiscalsim_us.model_api import * + + +class sc_tuition_credit(Variable): + """ + Tuition tax credit, refundable credit, line 21 on SC1040 2023 + Invidual Income Tax Return (see form I-319) + """ + + value_type = float + entity = Person + label = "South Carolina Tuition Credit" + defined_for = "sc_tuition_credit_eligible" + unit = USD + definition_period = YEAR + reference = ( + "https://dor.sc.gov/forms-site/Forms/I319_2023.pdf", + "https://dor.sc.gov/forms-site/Forms/I319_2021.pdf#page=2", + "https://www.scstatehouse.gov/code/t12c006.php", + # South Carolina Legal Code | SECTION 12-6-3385 (A) + ) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit_eligible.py b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit_eligible.py new file mode 100644 index 000000000..30c857f33 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/college_tuition/sc_tuition_credit_eligible.py @@ -0,0 +1,20 @@ +from fiscalsim_us.model_api import * + + +class sc_tuition_credit_eligible(Variable): + """ + Tuition tax credit, eligibility, refundable credit, line 21 on SC1040 2023 + Invidual Income Tax Return (see form I-319) + """ + + value_type = bool + entity = Person + label = "Eligible for the South Carolina Tuition Credit" + definition_period = YEAR + reference = ( + "https://dor.sc.gov/forms-site/Forms/I319_2023.pdf", + "https://dor.sc.gov/forms-site/Forms/I319_2021.pdf#page=2", + "https://www.scstatehouse.gov/code/t12c006.php", + # South Carolina Legal Code | SECTION 12-6-3385 (B)(3)(b) + ) + defined_for = StateCode.SC diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/eitc/sc_eitc.py b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/eitc/sc_eitc.py index 68fdb0d2f..fe7d1d59f 100644 --- a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/eitc/sc_eitc.py +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/eitc/sc_eitc.py @@ -8,8 +8,9 @@ class sc_eitc(Variable): unit = USD definition_period = YEAR reference = "https://dor.sc.gov/forms-site/Forms/TC60_2021.pdf" + defined_for = StateCode.SC def formula(tax_unit, period, parameters): - eitc = tax_unit("earned_income_tax_credit", period) + federal_eitc = tax_unit("eitc", period) rate = parameters(period).gov.states.sc.tax.income.credits.eitc.rate - return np.round(eitc * rate, 1) + return np.round(federal_eitc * rate, 1) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/two_wage_earner/sc_gross_earned_income.py b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/two_wage_earner/sc_gross_earned_income.py index 5b350b050..172e89da8 100644 --- a/fiscalsim_us/variables/gov/states/sc/tax/income/credits/two_wage_earner/sc_gross_earned_income.py +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/credits/two_wage_earner/sc_gross_earned_income.py @@ -9,4 +9,12 @@ class sc_gross_earned_income(Variable): definition_period = YEAR defined_for = StateCode.SC - adds = "gov.states.sc.tax.income.credits.two_wage_earner.earned_income" + def formula(person, period, parameters): + p = parameters( + period + ).gov.states.sc.tax.income.credits.two_wage_earner.earned_income + # Based on the legal code and the tax form worksheet, + # we use earned income as the income base for the credit. + earned_income = person("earned_income", period) + subtractions = add(person, period, p.subtractions) + return max_(0, earned_income - subtractions) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/deductions/net_capital_gain/sc_net_capital_gain_deduction.py b/fiscalsim_us/variables/gov/states/sc/tax/income/deductions/net_capital_gain/sc_net_capital_gain_deduction.py index f2325b642..826bbe8fd 100644 --- a/fiscalsim_us/variables/gov/states/sc/tax/income/deductions/net_capital_gain/sc_net_capital_gain_deduction.py +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/deductions/net_capital_gain/sc_net_capital_gain_deduction.py @@ -15,8 +15,11 @@ class sc_net_capital_gain_deduction(Variable): ) def formula(tax_unit, period, parameters): + ltcg = add(tax_unit, period, ["long_term_capital_gains"]) + stcg = add(tax_unit, period, ["short_term_capital_gains"]) + capped_stcg = min_(0, stcg) + base = max_(0, ltcg + capped_stcg) p = parameters( period ).gov.states.sc.tax.income.deductions.net_capital_gain - capital_gains = tax_unit("net_capital_gain", period) - return capital_gains * p.rate + return base * p.rate diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/deductions/sc_young_child_deduction.py b/fiscalsim_us/variables/gov/states/sc/tax/income/deductions/sc_young_child_deduction.py new file mode 100644 index 000000000..88b2ce89a --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/deductions/sc_young_child_deduction.py @@ -0,0 +1,29 @@ +from fiscalsim_us.model_api import * + + +class sc_young_child_deduction(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina young child deduction" + unit = USD + definition_period = YEAR + reference = ( + "https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2", + "https://www.scstatehouse.gov/code/t12c006.php", + # SECTION 12-6-1160 + ) + defined_for = StateCode.SC + + def formula(tax_unit, period, parameters): + # Get relevant parameter subtree. + p = parameters(period).gov.states.sc.tax.income.deductions.young_child + # Determine eligibility for each person in the tax unit. + person = tax_unit.members + meets_age_limit = person("age", period) < p.ineligible_age + eligible_dependent = meets_age_limit & person( + "is_tax_unit_dependent", period + ) + # Count number of eligible people in the tax unit. + total_eligible_dependents = tax_unit.sum(eligible_dependent) + # Multiply by the amount per eligible dependent. + return total_eligible_dependents * p.amount diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.py b/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.py new file mode 100644 index 000000000..c182cea09 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/sc_dependent_exemption.py @@ -0,0 +1,23 @@ +from fiscalsim_us.model_api import * + + +class sc_dependent_exemption(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina dependent exemption" + unit = USD + definition_period = YEAR + reference = ( + "https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf#page=2", + "https://www.scstatehouse.gov/code/t12c006.php", + # SECTION 12-6-1140 (13) + ) + defined_for = StateCode.SC + + def formula(tax_unit, period, parameters): + # Get relevant parameter subtree. The amount for dependent exemption is the same amount as the the young_child's. + p = parameters(period).gov.states.sc.tax.income.deductions.young_child + # every dependent is eligible + dependents = tax_unit("tax_unit_dependents", period) + # Multiply by the amount per exemption. + return dependents * p.amount diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/sc_senior_exemption.py b/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/sc_senior_exemption.py deleted file mode 100644 index 90e8d8fd1..000000000 --- a/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/sc_senior_exemption.py +++ /dev/null @@ -1,59 +0,0 @@ -from fiscalsim_us.model_api import * - - -class sc_senior_exemption(Variable): - value_type = float - entity = TaxUnit - label = "South Carolina senior exemption" - unit = USD - definition_period = YEAR - reference = "https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf" - defined_for = StateCode.SC - - def formula(tax_unit, period, parameters): - # First get their filing status. - filing_status = tax_unit("filing_status", period) - - # Then get the SC senior exemptions part of the parameter tree - p = parameters(period).gov.states.sc.tax.income.exemptions.senior - - # Get the individual filer's age. - age_head = tax_unit("age_head", period) - - # Determine if head of household (filer) is eligible. - head_eligible = (age_head >= p.age_threshold).astype(int) - - # Get the spouse age, if applicable. - age_spouse = tax_unit("age_spouse", period) - - # Determine whether spouse is eligible (>= age 65). - joint = filing_status == filing_status.possible_values.JOINT - spouse_eligible = ((age_spouse >= p.age_threshold) * joint).astype(int) - - # Get SC retirement income deduction and military retirement income deduction - - head_deductions = add( - tax_unit, - period, - [ - "sc_retirement_income_deduction_head", - "sc_military_retirement_income_deduction_head", - ], - ) - spouse_deductions = add( - tax_unit, - period, - [ - "sc_retirement_income_deduction_spouse", - "sc_military_retirement_income_deduction_spouse", - ], - ) - - # Calculate senior exemption. The exemption can not be less than 0. Add head and spouse together. - # Per the legal code, this applies separately: - # "(2) In the case of married taxpayers who file a joint federal income tax return, the reduction required by item (1) applies to each individual separately" - head_exemption = max_(head_eligible * p.amount - head_deductions, 0) - spouse_exemption = max_( - spouse_eligible * p.spouse_amount - spouse_deductions, 0 - ) - return head_exemption + spouse_exemption diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/senior/sc_senior_exemption.py b/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/senior/sc_senior_exemption.py new file mode 100644 index 000000000..c942bf2e8 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/senior/sc_senior_exemption.py @@ -0,0 +1,13 @@ +from fiscalsim_us.model_api import * + + +class sc_senior_exemption(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina senior exemption" + unit = USD + definition_period = YEAR + reference = "https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf" + defined_for = StateCode.SC + + adds = ["sc_senior_exemption_person"] diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/senior/sc_senior_exemption_person.py b/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/senior/sc_senior_exemption_person.py new file mode 100644 index 000000000..af7938965 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/exemptions/senior/sc_senior_exemption_person.py @@ -0,0 +1,40 @@ +from fiscalsim_us.model_api import * + + +class sc_senior_exemption_person(Variable): + value_type = float + entity = Person + label = "South Carolina senior exemption for each person" + unit = USD + definition_period = YEAR + reference = "https://dor.sc.gov/forms-site/Forms/SC1040_2022.pdf" + defined_for = StateCode.SC + + def formula(person, period, parameters): + # Get the SC senior exemptions part of the parameter tree + p = parameters(period).gov.states.sc.tax.income.exemptions.senior + + # Get the individual filer's age. + age = person("age", period) + + # Determine if head of household (filer) is eligible. + age_eligible = age >= p.age_threshold + + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + + eligible = head_or_spouse & age_eligible + # Get SC retirement income deduction and military retirement income deduction + + total_deductions = add( + person, + period, + [ + "sc_retirement_deduction_indv", + "sc_military_deduction_indv", + ], + ) + + # Calculate senior exemption. The exemption can not be less than 0. + reduced_max_amount = max_(p.amount - total_deductions, 0) + + return eligible * reduced_max_amount diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax.py b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax.py new file mode 100644 index 000000000..46ed93fb2 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax.py @@ -0,0 +1,18 @@ +from fiscalsim_us.model_api import * + + +class sc_income_tax(Variable): + """ + South Carolina income tax liability, from line 30 or line 34 of form SC1040 + 2023 Individual Income Tax Return + """ + + value_type = float + entity = TaxUnit + label = "South Carolina income tax" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + + adds = ["sc_income_tax_before_refundable_credits"] + subtracts = ["sc_refundable_credits"] diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax_before_non_refundable_credits.py b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax_before_non_refundable_credits.py new file mode 100644 index 000000000..f49208bd1 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax_before_non_refundable_credits.py @@ -0,0 +1,16 @@ +from fiscalsim_us.model_api import * + + +class sc_income_tax_before_non_refundable_credits(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina income tax before non-refundable credits" + defined_for = StateCode.SC + unit = USD + definition_period = YEAR + reference = "https://dor.sc.gov/forms-site/Forms/SC1040TT_2022.pdf" + + def formula(tax_unit, period, parameters): + taxable_income = tax_unit("sc_taxable_income", period) + p = parameters(period).gov.states.sc.tax.income.rates + return p.calc(taxable_income) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax_before_refundable_credits.py b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax_before_refundable_credits.py new file mode 100644 index 000000000..88a52051f --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_income_tax_before_refundable_credits.py @@ -0,0 +1,22 @@ +from fiscalsim_us.model_api import * + + +class sc_income_tax_before_refundable_credits(Variable): + """ + South Carolina income tax before refundable credits, line 15 on form SC1040 + 2023 Individual Income Tax Return + """ + + value_type = float + entity = TaxUnit + label = "South Carolina income tax before refundable credits" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + + def formula(tax_unit, period, parameters): + before_non_refundable_credits = tax_unit( + "sc_income_tax_before_non_refundable_credits", period + ) + non_refundable_credits = tax_unit("sc_non_refundable_credits", period) + return max_(before_non_refundable_credits - non_refundable_credits, 0) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_non_refundable_credits.py b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_non_refundable_credits.py new file mode 100644 index 000000000..85d38461b --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_non_refundable_credits.py @@ -0,0 +1,12 @@ +from fiscalsim_us.model_api import * + + +class sc_non_refundable_credits(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina non-refundable credits" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + + adds = "gov.states.sc.tax.income.credits.non_refundable" diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_refundable_credits.py b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_refundable_credits.py new file mode 100644 index 000000000..7e0d07413 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_refundable_credits.py @@ -0,0 +1,12 @@ +from fiscalsim_us.model_api import * + + +class sc_refundable_credits(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina refundable credits" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + + adds = "gov.states.sc.tax.income.credits.refundable" diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_taxable_income.py b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_taxable_income.py index 1a8dcff6c..8bf98152d 100644 --- a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_taxable_income.py +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_taxable_income.py @@ -1,10 +1,23 @@ -from fiscalsim_us.model_api import * - - -class sc_taxable_income(Variable): - value_type = float - entity = TaxUnit - label = "South Carolina taxable income" - defined_for = StateCode.SC - unit = USD - definition_period = YEAR +from fiscalsim_us.model_api import * + + +class sc_taxable_income(Variable): + """ + South Carolina income subject to tax, line 5 on SC1040 2023 + """ + + value_type = float + entity = TaxUnit + label = "South Carolina taxable income" + defined_for = StateCode.SC + unit = USD + definition_period = YEAR + reference = ( + "https://dor.sc.gov/forms-site/Forms/IITPacket_2023.pdf#page=43" + ) + + def formula(tax_unit, period, parameters): + taxable_income = tax_unit("taxable_income", period) + additions = tax_unit("sc_additions", period) + subtractions = tax_unit("sc_subtractions", period) + return max_(0, taxable_income + additions - subtractions) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/sc_withheld_income_tax.py b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_withheld_income_tax.py new file mode 100644 index 000000000..a9ffee7e8 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/sc_withheld_income_tax.py @@ -0,0 +1,19 @@ +from fiscalsim_us.model_api import * + + +class sc_withheld_income_tax(Variable): + value_type = float + entity = Person + label = "South Carolina withheld income tax" + defined_for = StateCode.SC + unit = USD + definition_period = YEAR + + def formula(person, period, parameters): + agi = person("adjusted_gross_income_person", period) + p_irs = parameters(period).gov.irs.deductions.standard + # We apply the base IRS standard deduction amount + standard_deduction = p_irs.amount["SINGLE"] + reduced_agi = max_(agi - standard_deduction, 0) + p = parameters(period).gov.states.sc.tax.income + return p.rates.calc(reduced_agi) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction.py new file mode 100644 index 000000000..e72bb268c --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction.py @@ -0,0 +1,19 @@ +from fiscalsim_us.model_api import * + + +class sc_military_deduction(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina military retirement deduction" + defined_for = StateCode.SC + unit = USD + reference = ( + "https://www.scstatehouse.gov/code/t12c006.php", # SECTION 12-6-1171(A) + "https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=17", + ) + definition_period = YEAR + + adds = [ + "sc_military_deduction_indv", # p4, p5 + "sc_military_deduction_survivors", # p6 + ] diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_indv.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_indv.py new file mode 100644 index 000000000..397ab1333 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_indv.py @@ -0,0 +1,18 @@ +from fiscalsim_us.model_api import * + + +class sc_military_deduction_indv(Variable): + value_type = float + entity = Person + label = "South Carolina military deduction for eligible individuals" + unit = USD + reference = ( + "https://www.scstatehouse.gov/code/t12c006.php", # SECTION 12-6-1171(A) + "https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=17", + ) + definition_period = YEAR + defined_for = StateCode.SC + + def formula(person, period, parameters): + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + return person("military_retirement_pay", period) * head_or_spouse diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_survivors.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_survivors.py new file mode 100644 index 000000000..83f39bec8 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/military_retirement/sc_military_deduction_survivors.py @@ -0,0 +1,17 @@ +from fiscalsim_us.model_api import * + + +class sc_military_deduction_survivors(Variable): + value_type = float + entity = Person + label = "South Carolina military retirement deduction for survivors" + defined_for = StateCode.SC + unit = USD + reference = ( + "https://www.scstatehouse.gov/code/t12c006.php", # SECTION 12-6-1171(C) + "https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=17", + ) + definition_period = YEAR + + def formula(person, period, parameters): + return person("military_retirement_pay_survivors", period) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_cap.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_cap.py new file mode 100644 index 000000000..ad7557a7d --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_cap.py @@ -0,0 +1,15 @@ +from fiscalsim_us.model_api import * + + +class sc_retirement_cap(Variable): + value_type = float + entity = Person + label = "South Carolina retirement income subtraction cap" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + + def formula(person, period, parameters): + p = parameters(period).gov.states.sc.tax.income.subtractions.retirement + age = person("age", period) + return p.cap.calc(age) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction.py new file mode 100644 index 000000000..6c885d895 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction.py @@ -0,0 +1,15 @@ +from fiscalsim_us.model_api import * + + +class sc_retirement_deduction(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina retirement deduction" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + + adds = [ + "sc_retirement_deduction_indv", # p1,p2 + "sc_retirement_deduction_survivors", # p3 + ] diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_indv.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_indv.py new file mode 100644 index 000000000..7220ed8a1 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_indv.py @@ -0,0 +1,33 @@ +from fiscalsim_us.model_api import * + + +class sc_retirement_deduction_indv(Variable): + value_type = float + entity = Person + label = "South Carolina retirement deduction for eligible individuals" + unit = USD + reference = ( + "https://www.scstatehouse.gov/code/t12c006.php", # SECTION 12-6-1170(A)(1) + "https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=17", + ) + definition_period = YEAR + defined_for = StateCode.SC + + def formula(person, period, parameters): + p = parameters(period).gov.states.sc.tax.income.subtractions.retirement + age = person("age", period) + head_or_spouse = person("is_tax_unit_head_or_spouse", period) + # line 1 + max_deduction_allowed = p.cap.calc(age) + # line 2 + military_retirement_pay = person("military_retirement_pay", period) + # line 3 + retirement_deduction_available = max_( + max_deduction_allowed - military_retirement_pay, 0 + ) + # line 4 + retirement_income = ( + person("taxable_pension_income", period) * head_or_spouse + ) + # line 5 + return min_(retirement_deduction_available, retirement_income) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.py new file mode 100644 index 000000000..aa1635958 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/retirement/sc_retirement_deduction_survivors.py @@ -0,0 +1,38 @@ +from fiscalsim_us.model_api import * + + +class sc_retirement_deduction_survivors(Variable): + value_type = float + entity = Person + label = "South Carolina retirement deduction for survivors" + defined_for = StateCode.SC + unit = USD + reference = ( + "https://www.scstatehouse.gov/code/t12c006.php", # SECTION 12-6-1170(A)(1) + "https://dor.sc.gov/forms-site/Forms/IITPacket_2021.pdf#page=17", + ) + definition_period = YEAR + + def formula(person, period, parameters): + p = parameters(period).gov.states.sc.tax.income.subtractions.retirement + age = person("age", period) + # line 1 + max_deduction_allowed = p.cap.calc(age) + # line 2 + military_retirement_pay_survivors = person( + "military_retirement_pay_survivors", period + ) + # line 3 + retirement_deduction_available = max_( + max_deduction_allowed - military_retirement_pay_survivors, 0 + ) + # line 4 + retirement_income_survivors = person("pension_survivors", period) + # In 2021, South Carolina subtracts the survivors retirement deduction from the military retirement deduction + # In 2022, it does not + cap = ( + retirement_deduction_available + if p.subtract_military + else max_deduction_allowed + ) + return min_(retirement_income_survivors, cap) diff --git a/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/sc_subtractions.py b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/sc_subtractions.py new file mode 100644 index 000000000..f910e4fc0 --- /dev/null +++ b/fiscalsim_us/variables/gov/states/sc/tax/income/subtractions/sc_subtractions.py @@ -0,0 +1,11 @@ +from fiscalsim_us.model_api import * + + +class sc_subtractions(Variable): + value_type = float + entity = TaxUnit + label = "South Carolina subtractions" + unit = USD + definition_period = YEAR + defined_for = StateCode.SC + adds = "gov.states.sc.tax.income.subtractions.subtractions" diff --git a/fiscalsim_us/variables/gov/states/tax/income/state_income_tax.py b/fiscalsim_us/variables/gov/states/tax/income/state_income_tax.py index ad61e5f24..a1ce6cea6 100644 --- a/fiscalsim_us/variables/gov/states/tax/income/state_income_tax.py +++ b/fiscalsim_us/variables/gov/states/tax/income/state_income_tax.py @@ -35,6 +35,7 @@ class state_income_tax(Variable): "or_income_tax", "pa_income_tax", "ri_income_tax", + "sc_income_tax", "ut_income_tax", "va_income_tax", "vt_income_tax", diff --git a/fiscalsim_us/variables/gov/states/tax/income/state_income_tax_before_refundable_credits.py b/fiscalsim_us/variables/gov/states/tax/income/state_income_tax_before_refundable_credits.py index 10ddd02fa..abade4ee9 100644 --- a/fiscalsim_us/variables/gov/states/tax/income/state_income_tax_before_refundable_credits.py +++ b/fiscalsim_us/variables/gov/states/tax/income/state_income_tax_before_refundable_credits.py @@ -34,6 +34,7 @@ class state_income_tax_before_refundable_credits(Variable): "or_income_tax_before_refundable_credits", "pa_income_tax", # PA has no refundable credits. "ri_income_tax_before_refundable_credits", + "sc_income_tax_before_refundable_credits", "ut_income_tax_before_refundable_credits", "va_income_tax_before_refundable_credits", "vt_income_tax_before_refundable_credits", diff --git a/fiscalsim_us/variables/gov/states/unemployment_compensation.py b/fiscalsim_us/variables/gov/states/unemployment_compensation.py index eb972e4ed..165af5bf8 100644 --- a/fiscalsim_us/variables/gov/states/unemployment_compensation.py +++ b/fiscalsim_us/variables/gov/states/unemployment_compensation.py @@ -1,10 +1,11 @@ -from fiscalsim_us.model_api import * - - -class unemployment_compensation(Variable): - value_type = float - entity = Person - label = "unemployment compensation" - unit = USD - documentation = "Income from unemployment compensation programs." - definition_period = YEAR +from fiscalsim_us.model_api import * + + +class unemployment_compensation(Variable): + value_type = float + entity = Person + label = "unemployment compensation" + unit = USD + documentation = "Income from unemployment compensation programs." + definition_period = YEAR + uprating = "calibration.gov.irs.soi.unemployment_compensation" diff --git a/fiscalsim_us/variables/household/income/household/household_refundable_tax_credits.py b/fiscalsim_us/variables/household/income/household/household_refundable_tax_credits.py index 4abcc6618..836775bc1 100644 --- a/fiscalsim_us/variables/household/income/household/household_refundable_tax_credits.py +++ b/fiscalsim_us/variables/household/income/household/household_refundable_tax_credits.py @@ -8,40 +8,41 @@ class household_refundable_tax_credits(Variable): definition_period = YEAR unit = USD adds = [ - "income_tax_refundable_credits", # Federal. - "ca_refundable_credits", # California. - "co_refundable_credits", # Colorado. - "dc_refundable_credits", # District of Columbia. - "ia_refundable_credits", # Iowa. - "il_refundable_credits", # Illinois. - "in_refundable_credits", # Indiana. - "ks_refundable_credits", # Kansas. - "ky_refundable_credits", # Kentucky. - "la_refundable_credits", # Louisiana. - "ma_refundable_credits", # Massachusetts. - "me_refundable_credits", # Maine. - "md_refundable_credits", # Maryland. - "mn_refundable_credits", # Minnesota. - "mt_refundable_credits", # Montana. - "mo_refundable_credits", # Missouri. - # Skip NC, which has no refundable credits. - "nd_refundable_credits", # North Dakota. - "ne_refundable_credits", # Nebraska. - "nh_refundable_credits", # New Hampshire. - "nj_refundable_credits", # New Jersey. - "nm_refundable_credits", # New Mexico. - "ny_refundable_credits", # New York. - "ok_refundable_credits", # Oklahoma. - "or_refundable_credits", # Oregon. - # Skip PA, which has no refundable credits. - "ri_refundable_credits", # Rhode Island. - "ut_refundable_credits", # Utah. - "va_refundable_credits", # Virginia. - "vt_refundable_credits", # Vermont. - "wa_refundable_credits", # Washington. - "wi_refundable_credits", # Wisconsin. + "income_tax_refundable_credits", # Federal + "ca_refundable_credits", # California + "co_refundable_credits", # Colorado + "dc_refundable_credits", # District of Columbia + "ia_refundable_credits", # Iowa + "il_refundable_credits", # Illinois + "in_refundable_credits", # Indiana + "ks_refundable_credits", # Kansas + "ky_refundable_credits", # Kentucky + "la_refundable_credits", # Louisiana + "ma_refundable_credits", # Massachusetts + "me_refundable_credits", # Maine + "md_refundable_credits", # Maryland + "mn_refundable_credits", # Minnesota + "mt_refundable_credits", # Montana + "mo_refundable_credits", # Missouri + # Skip NC, which has no refundable credits + "nd_refundable_credits", # North Dakota + "ne_refundable_credits", # Nebraska + "nh_refundable_credits", # New Hampshire + "nj_refundable_credits", # New Jersey + "nm_refundable_credits", # New Mexico + "ny_refundable_credits", # New York + "ok_refundable_credits", # Oklahoma + "or_refundable_credits", # Oregon + # Skip PA, which has no refundable credits + "ri_refundable_credits", # Rhode Island + "sc_refundable_credits", # South Carolina + "ut_refundable_credits", # Utah + "va_refundable_credits", # Virginia + "vt_refundable_credits", # Vermont + "wa_refundable_credits", # Washington + "wi_refundable_credits", # Wisconsin # LOCAL - "nyc_refundable_credits", # New York City. + "nyc_refundable_credits", # New York City ] def formula(household, period, parameters): diff --git a/fiscalsim_us/variables/household/income/household/household_state_income_tax.py b/fiscalsim_us/variables/household/income/household/household_state_income_tax.py index 02fa574c6..51d5622e2 100644 --- a/fiscalsim_us/variables/household/income/household/household_state_income_tax.py +++ b/fiscalsim_us/variables/household/income/household/household_state_income_tax.py @@ -35,6 +35,7 @@ class household_state_income_tax(Variable): "or_income_tax_before_refundable_credits", "pa_income_tax", "ri_income_tax_before_refundable_credits", + "sc_income_tax_before_refundable_credits", "ut_income_tax_before_refundable_credits", "va_income_tax_before_refundable_credits", "vt_income_tax_before_refundable_credits", @@ -43,39 +44,40 @@ class household_state_income_tax(Variable): "nyc_income_tax_before_refundable_credits", ] subtracts = [ - "ca_refundable_credits", # California. + "ca_refundable_credits", # California "co_refundable_credits", # Colorado - "dc_refundable_credits", # District of Columbia. - "ia_refundable_credits", # Iowa. - "il_refundable_credits", # Illinois. - "in_refundable_credits", # Indiana. - "ks_refundable_credits", # Kansas. - "ky_refundable_credits", # Kentucky. - "la_refundable_credits", # Louisiana. - "ma_refundable_credits", # Massachusetts. - "me_refundable_credits", # Maine. - "md_refundable_credits", # Maryland. - "mn_refundable_credits", # Minnesota. - "mt_refundable_credits", # Montana. - "mo_refundable_credits", # Missouri. - # Skip NC, which has no refundable credits. - "nd_refundable_credits", # North Dakota. - "ne_refundable_credits", # Nebraska. - "nh_refundable_credits", # New Hampshire. - "nj_refundable_credits", # New Jersey. - "nm_refundable_credits", # New Mexico. - "ny_refundable_credits", # New York. - "ok_refundable_credits", # Oklahoma. - "or_refundable_credits", # Oregon. - # Skip PA, which has no refundable credits. - "ri_refundable_credits", # Rhode Island. - "ut_refundable_credits", # Utah. - "va_refundable_credits", # Virginia. - "vt_refundable_credits", # Vermont. - "wa_refundable_credits", # Washington. - "wi_refundable_credits", # Wisconsin. + "dc_refundable_credits", # District of Columbia + "ia_refundable_credits", # Iowa + "il_refundable_credits", # Illinois + "in_refundable_credits", # Indiana + "ks_refundable_credits", # Kansas + "ky_refundable_credits", # Kentucky + "la_refundable_credits", # Louisiana + "ma_refundable_credits", # Massachusetts + "me_refundable_credits", # Maine + "md_refundable_credits", # Maryland + "mn_refundable_credits", # Minnesota + "mt_refundable_credits", # Montana + "mo_refundable_credits", # Missouri + # Skip NC, which has no refundable credits + "nd_refundable_credits", # North Dakota + "ne_refundable_credits", # Nebraska + "nh_refundable_credits", # New Hampshire + "nj_refundable_credits", # New Jersey + "nm_refundable_credits", # New Mexico + "ny_refundable_credits", # New York + "ok_refundable_credits", # Oklahoma + "or_refundable_credits", # Oregon + # Skip PA, which has no refundable credits + "ri_refundable_credits", # Rhode Island + "sc_refundable_credits", # South Carolina + "ut_refundable_credits", # Utah + "va_refundable_credits", # Virginia + "vt_refundable_credits", # Vermont + "wa_refundable_credits", # Washington + "wi_refundable_credits", # Wisconsin # LOCAL - "nyc_refundable_credits", # New York City. + "nyc_refundable_credits", # New York City ] def formula(tax_unit, period, parameters): diff --git a/fiscalsim_us/variables/household/income/household/household_tax_before_refundable_credits.py b/fiscalsim_us/variables/household/income/household/household_tax_before_refundable_credits.py index 29eec83f7..f11aecbb3 100644 --- a/fiscalsim_us/variables/household/income/household/household_tax_before_refundable_credits.py +++ b/fiscalsim_us/variables/household/income/household/household_tax_before_refundable_credits.py @@ -38,6 +38,7 @@ class household_tax_before_refundable_credits(Variable): "or_income_tax_before_refundable_credits", "pa_income_tax", # PA has no refundable credits. "ri_income_tax_before_refundable_credits", + "sc_income_tax_before_refundable_credits", "ut_income_tax_before_refundable_credits", "va_income_tax_before_refundable_credits", "vt_income_tax_before_refundable_credits", diff --git a/fiscalsim_us/variables/household/income/person/pensions/military_retirement_pay.py b/fiscalsim_us/variables/household/income/person/pensions/military_retirement_pay.py deleted file mode 100644 index d2ac211fe..000000000 --- a/fiscalsim_us/variables/household/income/person/pensions/military_retirement_pay.py +++ /dev/null @@ -1,11 +0,0 @@ -from fiscalsim_us.model_api import * - - -class military_retirement_pay(Variable): - value_type = float - entity = Person - label = "ME military retirement pay subtractions" - unit = USD - definition_period = YEAR - documentation = "The benefits received under a United States military retirement plan, including survivor benefits, are fully exempt from Maine income tax. See 2022 - Worksheet for Pension Income Deduction below." - reference = "https://www.maine.gov/revenue/sites/maine.gov.revenue/files/inline-files/22_1040me_sched_1s_ff.pdf" diff --git a/fiscalsim_us/variables/household/income/person/retirement/csrs_retirement_pay.py b/fiscalsim_us/variables/household/income/person/retirement/csrs_retirement_pay.py new file mode 100644 index 000000000..40d701d22 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/csrs_retirement_pay.py @@ -0,0 +1,13 @@ +from fiscalsim_us.model_api import * + + +class csrs_retirement_pay(Variable): + value_type = float + entity = Person + label = "Civil Service Retirement System (CSRS) retirement income" + unit = USD + definition_period = YEAR + documentation = ( + "Retirement income from the federal Civil Service Retirement System." + ) + reference = "https://tax.vermont.gov/individuals/seniors-and-retirees" # Exemption for Civil Service Retirement System (CSRS) diff --git a/fiscalsim_us/variables/household/income/person/retirement/keogh_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/keogh_distributions.py new file mode 100644 index 000000000..6b66dd4bc --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/keogh_distributions.py @@ -0,0 +1,9 @@ +from fiscalsim_us.model_api import * + + +class keogh_distributions(Variable): + value_type = float + entity = Person + label = "Keogh plan distributions" + unit = USD + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/military_retirement_pay.py b/fiscalsim_us/variables/household/income/person/retirement/military_retirement_pay.py new file mode 100644 index 000000000..be1b734d7 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/military_retirement_pay.py @@ -0,0 +1,11 @@ +from fiscalsim_us.model_api import * + + +class military_retirement_pay(Variable): + value_type = float + entity = Person + label = "Military retirement pay" + unit = USD + definition_period = YEAR + documentation = "The benefits received under a United States military retirement plan, including survivor benefits." + reference = "https://militarypay.defense.gov/Pay/Retirement/" diff --git a/fiscalsim_us/variables/household/income/person/retirement/military_retirement_pay_survivors.py b/fiscalsim_us/variables/household/income/person/retirement/military_retirement_pay_survivors.py new file mode 100644 index 000000000..fb6eaa26f --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/military_retirement_pay_survivors.py @@ -0,0 +1,9 @@ +from fiscalsim_us.model_api import * + + +class military_retirement_pay_survivors(Variable): + value_type = float + entity = Person + label = "Military retirement income paid to surviving spouses" + unit = USD + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/pensions/pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/pension_income.py similarity index 96% rename from fiscalsim_us/variables/household/income/person/pensions/pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/pension_income.py index 761fa9305..f2352c125 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/pension_income.py @@ -1,14 +1,14 @@ -from fiscalsim_us.model_api import * - - -class pension_income(Variable): - value_type = float - entity = Person - label = "pension income" - unit = USD - documentation = "Income from pensions, annuitities, life insurance or endowment contracts." - definition_period = YEAR - adds = [ - "tax_exempt_pension_income", - "taxable_pension_income", - ] +from fiscalsim_us.model_api import * + + +class pension_income(Variable): + value_type = float + entity = Person + label = "pension income" + unit = USD + documentation = "Income from pensions, annuitities, life insurance or endowment contracts." + definition_period = YEAR + adds = [ + "tax_exempt_pension_income", + "taxable_pension_income", + ] diff --git a/fiscalsim_us/variables/household/income/person/pensions/pension_survivors.py b/fiscalsim_us/variables/household/income/person/retirement/pension_survivors.py similarity index 100% rename from fiscalsim_us/variables/household/income/person/pensions/pension_survivors.py rename to fiscalsim_us/variables/household/income/person/retirement/pension_survivors.py diff --git a/fiscalsim_us/variables/household/income/person/pensions/private_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/private_pension_income.py similarity index 96% rename from fiscalsim_us/variables/household/income/person/pensions/private_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/private_pension_income.py index 2290b4d66..cafc38f57 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/private_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/private_pension_income.py @@ -1,15 +1,15 @@ -from fiscalsim_us.model_api import * - - -class private_pension_income(Variable): - value_type = float - entity = Person - label = "private pension income" - unit = USD - documentation = "Income from non-government employee pensions." - definition_period = YEAR - - adds = [ - "tax_exempt_private_pension_income", - "taxable_private_pension_income", - ] +from fiscalsim_us.model_api import * + + +class private_pension_income(Variable): + value_type = float + entity = Person + label = "private pension income" + unit = USD + documentation = "Income from non-government employee pensions." + definition_period = YEAR + + adds = [ + "tax_exempt_private_pension_income", + "taxable_private_pension_income", + ] diff --git a/fiscalsim_us/variables/household/income/person/pensions/public_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/public_pension_income.py similarity index 96% rename from fiscalsim_us/variables/household/income/person/pensions/public_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/public_pension_income.py index 49f6a7125..9e8638fb9 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/public_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/public_pension_income.py @@ -1,15 +1,15 @@ -from fiscalsim_us.model_api import * - - -class public_pension_income(Variable): - value_type = float - entity = Person - label = "public pension income" - unit = USD - documentation = "Income from government employee pensions." - definition_period = YEAR - - adds = [ - "tax_exempt_public_pension_income", - "taxable_public_pension_income", - ] +from fiscalsim_us.model_api import * + + +class public_pension_income(Variable): + value_type = float + entity = Person + label = "public pension income" + unit = USD + documentation = "Income from government employee pensions." + definition_period = YEAR + + adds = [ + "tax_exempt_public_pension_income", + "taxable_public_pension_income", + ] diff --git a/fiscalsim_us/variables/household/income/person/retirement/railroad_benefits.py b/fiscalsim_us/variables/household/income/person/retirement/railroad_benefits.py new file mode 100644 index 000000000..346f0f939 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/railroad_benefits.py @@ -0,0 +1,9 @@ +from fiscalsim_us.model_api import * + + +class railroad_benefits(Variable): + value_type = float + entity = Person + label = "Receives any railroad benefits" + definition_period = YEAR + default_value = 0 diff --git a/fiscalsim_us/variables/household/income/person/retirement/retirement_benefits_from_ss_exempt_employment.py b/fiscalsim_us/variables/household/income/person/retirement/retirement_benefits_from_ss_exempt_employment.py new file mode 100644 index 000000000..b47d5d1ed --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/retirement_benefits_from_ss_exempt_employment.py @@ -0,0 +1,11 @@ +from fiscalsim_us.model_api import * + + +class retirement_benefits_from_ss_exempt_employment(Variable): + value_type = float + entity = Person + label = "Retirement benefits amount from SS exempt employment" + unit = USD + documentation = "Amount of a recipient receive retirement benefits from SS exempt employment" + reference = "https://www.michigan.gov/taxes/-/media/Project/Websites/taxes/Forms/2022/2022-IIT-Forms/BOOK_MI-1040.pdf#page=18" + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/retirement_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/retirement_distributions.py new file mode 100644 index 000000000..abe3eb31d --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/retirement_distributions.py @@ -0,0 +1,13 @@ +from fiscalsim_us.model_api import * + + +class retirement_distributions(Variable): + value_type = float + entity = Person + label = "Retirement account distributions" + unit = USD + definition_period = YEAR + adds = [ + "taxable_retirement_distributions", + "tax_exempt_retirement_distributions", + ] diff --git a/fiscalsim_us/variables/household/income/person/retirement/sep_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/sep_distributions.py new file mode 100644 index 000000000..749b23d53 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/sep_distributions.py @@ -0,0 +1,10 @@ +from fiscalsim_us.model_api import * + + +class sep_distributions(Variable): + value_type = float + entity = Person + label = "SEP distributions" + unit = USD + definition_period = YEAR + adds = ["taxable_sep_distributions", "tax_exempt_sep_distributions"] diff --git a/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_401k_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_401k_distributions.py new file mode 100644 index 000000000..fda9ee0d8 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_401k_distributions.py @@ -0,0 +1,12 @@ +from fiscalsim_us.model_api import * + + +class tax_exempt_401k_distributions(Variable): + value_type = float + entity = Person + label = "Tax-exempt 401(k) distributions" + unit = USD + documentation = ( + "Tax-exempt distributions from 401(k) accounts (typically Roth)." + ) + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_403b_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_403b_distributions.py new file mode 100644 index 000000000..63f2785b1 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_403b_distributions.py @@ -0,0 +1,12 @@ +from fiscalsim_us.model_api import * + + +class tax_exempt_403b_distributions(Variable): + value_type = float + entity = Person + label = "tax-exempt 403(b) distributions" + unit = USD + documentation = ( + "Tax-exempt distributions from 403(b) accounts (typically Roth)." + ) + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_ira_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_ira_distributions.py new file mode 100644 index 000000000..f3f13210c --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_ira_distributions.py @@ -0,0 +1,10 @@ +from fiscalsim_us.model_api import * + + +class tax_exempt_ira_distributions(Variable): + value_type = float + entity = Person + label = "Tax-exempt IRA distributions" + unit = USD + documentation = "Tax-exempt distributions from individual retirement accounts (qualifying Roth distributions)." + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/pensions/tax_exempt_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_pension_income.py similarity index 95% rename from fiscalsim_us/variables/household/income/person/pensions/tax_exempt_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/tax_exempt_pension_income.py index 904cf1975..46d852a21 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/tax_exempt_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_pension_income.py @@ -1,14 +1,14 @@ -from fiscalsim_us.model_api import * - - -class tax_exempt_pension_income(Variable): - value_type = float - entity = Person - label = "tax-exempt pension income" - unit = USD - definition_period = YEAR - - adds = [ - "tax_exempt_public_pension_income", - "tax_exempt_private_pension_income", - ] +from fiscalsim_us.model_api import * + + +class tax_exempt_pension_income(Variable): + value_type = float + entity = Person + label = "tax-exempt pension income" + unit = USD + definition_period = YEAR + + adds = [ + "tax_exempt_public_pension_income", + "tax_exempt_private_pension_income", + ] diff --git a/fiscalsim_us/variables/household/income/person/pensions/tax_exempt_private_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_private_pension_income.py similarity index 96% rename from fiscalsim_us/variables/household/income/person/pensions/tax_exempt_private_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/tax_exempt_private_pension_income.py index 0b3e5d646..9ae20372a 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/tax_exempt_private_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_private_pension_income.py @@ -1,10 +1,10 @@ -from fiscalsim_us.model_api import * - - -class tax_exempt_private_pension_income(Variable): - value_type = float - entity = Person - label = "tax-exempt private pension income" - unit = USD - documentation = "Tax-exempt income from non-government employee pensions." - definition_period = YEAR +from fiscalsim_us.model_api import * + + +class tax_exempt_private_pension_income(Variable): + value_type = float + entity = Person + label = "tax-exempt private pension income" + unit = USD + documentation = "Tax-exempt income from non-government employee pensions." + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/pensions/tax_exempt_public_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_public_pension_income.py similarity index 96% rename from fiscalsim_us/variables/household/income/person/pensions/tax_exempt_public_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/tax_exempt_public_pension_income.py index 8f201a79c..f15949f87 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/tax_exempt_public_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_public_pension_income.py @@ -1,10 +1,10 @@ -from fiscalsim_us.model_api import * - - -class tax_exempt_public_pension_income(Variable): - value_type = float - entity = Person - label = "tax-exempt public pension income" - unit = USD - documentation = "Tax-exempt income from government employee pensions." - definition_period = YEAR +from fiscalsim_us.model_api import * + + +class tax_exempt_public_pension_income(Variable): + value_type = float + entity = Person + label = "tax-exempt public pension income" + unit = USD + documentation = "Tax-exempt income from government employee pensions." + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_retirement_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_retirement_distributions.py new file mode 100644 index 000000000..0e52e4387 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_retirement_distributions.py @@ -0,0 +1,15 @@ +from fiscalsim_us.model_api import * + + +class tax_exempt_retirement_distributions(Variable): + value_type = float + entity = Person + label = "Tax-exempt retirement account distributions" + unit = USD + definition_period = YEAR + adds = [ + "tax_exempt_ira_distributions", + "tax_exempt_401k_distributions", + "tax_exempt_sep_distributions", + "tax_exempt_403b_distributions", + ] diff --git a/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_sep_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_sep_distributions.py new file mode 100644 index 000000000..8ec461fa2 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/tax_exempt_sep_distributions.py @@ -0,0 +1,9 @@ +from fiscalsim_us.model_api import * + + +class tax_exempt_sep_distributions(Variable): + value_type = float + entity = Person + label = "tax-exempt SEP distributions" + unit = USD + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/taxable_401k_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_401k_distributions.py new file mode 100644 index 000000000..00709140d --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_401k_distributions.py @@ -0,0 +1,12 @@ +from fiscalsim_us.model_api import * + + +class taxable_401k_distributions(Variable): + value_type = float + entity = Person + label = "Taxable 401(k) distributions" + unit = USD + documentation = ( + "Taxable distributions from 401k accounts (typically traditional)." + ) + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/taxable_403b_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_403b_distributions.py new file mode 100644 index 000000000..f9bd0b36f --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_403b_distributions.py @@ -0,0 +1,12 @@ +from fiscalsim_us.model_api import * + + +class taxable_403b_distributions(Variable): + value_type = float + entity = Person + label = "Taxable 403(b) distributions" + unit = USD + documentation = ( + "Taxable distributions from 403b accounts (typically traditional)." + ) + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/pensions/taxable_federal_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_federal_pension_income.py similarity index 100% rename from fiscalsim_us/variables/household/income/person/pensions/taxable_federal_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/taxable_federal_pension_income.py diff --git a/fiscalsim_us/variables/household/income/person/retirement/taxable_ira_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_ira_distributions.py new file mode 100644 index 000000000..3af956eee --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_ira_distributions.py @@ -0,0 +1,10 @@ +from fiscalsim_us.model_api import * + + +class taxable_ira_distributions(Variable): + value_type = float + entity = Person + label = "Taxable IRA distributions" + unit = USD + documentation = "Taxable distributions from individual retirement accounts (typically traditional IRAs)." + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/pensions/taxable_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_pension_income.py similarity index 81% rename from fiscalsim_us/variables/household/income/person/pensions/taxable_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/taxable_pension_income.py index 239ba8617..5d1403af1 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/taxable_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_pension_income.py @@ -1,11 +1,12 @@ -from fiscalsim_us.model_api import * - - -class taxable_pension_income(Variable): - value_type = float - entity = Person - label = "taxable pension income" - unit = USD - definition_period = YEAR - - adds = ["taxable_public_pension_income", "taxable_private_pension_income"] +from fiscalsim_us.model_api import * + + +class taxable_pension_income(Variable): + value_type = float + entity = Person + label = "taxable pension income" + unit = USD + definition_period = YEAR + uprating = "calibration.gov.irs.soi.taxable_pension_income" + + adds = ["taxable_public_pension_income", "taxable_private_pension_income"] diff --git a/fiscalsim_us/variables/household/income/person/pensions/taxable_private_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_private_pension_income.py similarity index 96% rename from fiscalsim_us/variables/household/income/person/pensions/taxable_private_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/taxable_private_pension_income.py index a749368cc..0635fdc5a 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/taxable_private_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_private_pension_income.py @@ -1,10 +1,10 @@ -from fiscalsim_us.model_api import * - - -class taxable_private_pension_income(Variable): - value_type = float - entity = Person - label = "taxable private pension income" - unit = USD - documentation = "Taxable income from non-government employee pensions." - definition_period = YEAR +from fiscalsim_us.model_api import * + + +class taxable_private_pension_income(Variable): + value_type = float + entity = Person + label = "taxable private pension income" + unit = USD + documentation = "Taxable income from non-government employee pensions." + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/pensions/taxable_public_pension_income.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_public_pension_income.py similarity index 96% rename from fiscalsim_us/variables/household/income/person/pensions/taxable_public_pension_income.py rename to fiscalsim_us/variables/household/income/person/retirement/taxable_public_pension_income.py index fa398c37c..b88da7097 100644 --- a/fiscalsim_us/variables/household/income/person/pensions/taxable_public_pension_income.py +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_public_pension_income.py @@ -1,10 +1,10 @@ -from fiscalsim_us.model_api import * - - -class taxable_public_pension_income(Variable): - value_type = float - entity = Person - label = "taxable public pension income" - unit = USD - documentation = "Taxable income from government employee pensions." - definition_period = YEAR +from fiscalsim_us.model_api import * + + +class taxable_public_pension_income(Variable): + value_type = float + entity = Person + label = "taxable public pension income" + unit = USD + documentation = "Taxable income from government employee pensions." + definition_period = YEAR diff --git a/fiscalsim_us/variables/household/income/person/retirement/taxable_retirement_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_retirement_distributions.py new file mode 100644 index 000000000..847a72f44 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_retirement_distributions.py @@ -0,0 +1,16 @@ +from fiscalsim_us.model_api import * + + +class taxable_retirement_distributions(Variable): + value_type = float + entity = Person + label = "Taxable retirement account distributions" + unit = USD + definition_period = YEAR + adds = [ + "taxable_ira_distributions", + "taxable_401k_distributions", + "taxable_sep_distributions", + "taxable_403b_distributions", + "keogh_distributions", + ] diff --git a/fiscalsim_us/variables/household/income/person/retirement/taxable_sep_distributions.py b/fiscalsim_us/variables/household/income/person/retirement/taxable_sep_distributions.py new file mode 100644 index 000000000..90abb4966 --- /dev/null +++ b/fiscalsim_us/variables/household/income/person/retirement/taxable_sep_distributions.py @@ -0,0 +1,9 @@ +from fiscalsim_us.model_api import * + + +class taxable_sep_distributions(Variable): + value_type = float + entity = Person + label = "taxable SEP distributions" + unit = USD + definition_period = YEAR diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..ac83d1290 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +# Configuration for Black. + +# NOTE: you have to use single-quoted strings in TOML for regular expressions. +# It's the equivalent of r-strings in Python. Multiline strings are treated as +# verbose regular expressions by Black. Use [ ] to denote a significant space +# character. + +[tool.black] +line-length = 79 +target-version = ["py310", "py311"] +include = '\.pyi?$' diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..bdde10c06 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +# pytest.ini +[pytest] +minversion = 6.0 +testpaths = + ./fiscalsim_us/tests +markers = + local: marks tests that run locally and not on GH Actions (mostly due to run time) diff --git a/setup.py b/setup.py index 3a6f532e9..3731f715f 100644 --- a/setup.py +++ b/setup.py @@ -7,9 +7,9 @@ setup( name="fiscalsim-us", - version="0.2.9", - author="Center for Growth and Opportunity at Utah State University (CGO)", - author_email="fiscalsim@thecgo.org", + version="0.3.0", + author="Richard W. Evans", + author_email="rick@abundance.institute", long_description=readme, long_description_content_type="text/markdown", classifiers=[ @@ -54,16 +54,17 @@ "autopep8", "black", "coverage", - "jupyter-book", + "jupyter-book>=0.11.3", "jupyter", "linecheck", "markupsafe", "plotly", "bokeh>=3.1.1", - "pydata-sphinx-theme==0.13.1", + "pydata-sphinx-theme", "setuptools", - "sphinx", + "sphinx>=3.5.4", "sphinx-argparse", + "sphinxcontrib-bibtex>=2.0.0", "sphinx-math-dollar", "wheel", "yaml-changelog",