From 82505fc684e5d11c31429e5a2baf0fd0f892603c Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Tue, 12 May 2026 09:30:41 -0400 Subject: [PATCH 1/7] Initial commit for Oklahoma Unemployment Insurance implementation Starting implementation of Oklahoma UI per issue #8264. Documentation and implementation will follow. From e1971a87cbad99d11c0061fa948f672542f34da3 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Tue, 12 May 2026 11:59:45 -0400 Subject: [PATCH 2/7] Implement Oklahoma Unemployment Insurance (ref #8264) Co-Authored-By: Claude Opus 4.7 (1M context) --- changelog.d/ok-ui.added.md | 1 + .../eligibility/min_taxable_wages.yaml | 12 + .../min_total_wages_multiplier.yaml | 12 + .../ok/oesc/unemployment_insurance/index.yaml | 4 + .../unemployment_insurance/mba/max_weeks.yaml | 17 + .../partial/disregard.yaml | 12 + .../unemployment_insurance/wba/divisor.yaml | 12 + .../wba/max_amount.yaml | 20 + .../wba/min_amount.yaml | 12 + .../unemployment/taxable_wage_base.yaml | 17 +- .../unemployment_insurance/edge_cases.yaml | 505 ++++++++++++++++++ .../unemployment_insurance/integration.yaml | 209 ++++++++ .../ok/oesc/unemployment_insurance/ok_ui.yaml | 83 +++ .../ok_ui_maximum_benefit_amount.yaml | 44 ++ .../ok_ui_meets_alternate_wages_test.yaml | 65 +++ .../ok_ui_meets_high_quarter_test.yaml | 84 +++ .../ok_ui_monetarily_eligible.yaml | 74 +++ .../ok_ui_weekly_benefit_rate.yaml | 101 ++++ .../ok_ui_weekly_payable.yaml | 98 ++++ .../ok/oesc/unemployment_insurance/ok_ui.py | 36 ++ .../ok_ui_base_period_taxable_wages.py | 23 + .../ok_ui_base_period_total_wages.py | 22 + .../ok_ui_gross_weekly_earnings.py | 20 + .../ok_ui_high_quarter_taxable_wages.py | 22 + .../ok_ui_maximum_benefit_amount.py | 24 + .../ok_ui_meets_alternate_wages_test.py | 22 + .../ok_ui_meets_high_quarter_test.py | 23 + .../ok_ui_monetarily_eligible.py | 17 + .../ok_ui_weekly_benefit_rate.py | 23 + .../ok_ui_weekly_payable.py | 23 + 30 files changed, 1633 insertions(+), 4 deletions(-) create mode 100644 changelog.d/ok-ui.added.md create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/index.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.yaml create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_high_quarter_taxable_wages.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py create mode 100644 policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py diff --git a/changelog.d/ok-ui.added.md b/changelog.d/ok-ui.added.md new file mode 100644 index 00000000000..95dae71528a --- /dev/null +++ b/changelog.d/ok-ui.added.md @@ -0,0 +1 @@ +Add Oklahoma Unemployment Insurance. diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml new file mode 100644 index 00000000000..9d5366c0245 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml @@ -0,0 +1,12 @@ +description: Oklahoma sets the minimum taxable base period wages at this amount for monetary eligibility under the Unemployment Insurance program. + +values: + 1980-07-01: 1_500 + +metadata: + unit: currency-USD + period: year + label: Oklahoma UI minimum taxable base period wages + reference: + - title: 40 O.S. §2-207(A) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml new file mode 100644 index 00000000000..81bcccc57d1 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml @@ -0,0 +1,12 @@ +description: Oklahoma uses this share of high quarter wages as the minimum total base period wages for monetary eligibility under the Unemployment Insurance program. + +values: + 1980-07-01: 1.5 + +metadata: + unit: /1 + period: year + label: Oklahoma UI minimum total wages multiplier + reference: + - title: 40 O.S. §2-207(A) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/index.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/index.yaml new file mode 100644 index 00000000000..cb39cde8a79 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/index.yaml @@ -0,0 +1,4 @@ +metadata: + propagate_metadata_to_children: true + economy: false + household: true diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml new file mode 100644 index 00000000000..8aeb073b58f --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml @@ -0,0 +1,17 @@ +description: Oklahoma limits unemployment compensation benefits to this number of weeks within a benefit year under the Unemployment Insurance program. + +values: + 0000-01-01: 26 + 2023-01-01: 16 + +metadata: + unit: week + period: year + label: Oklahoma UI maximum benefit weeks + reference: + - title: 40 O.S. §1-231 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=48 + - title: 40 O.S. §2-106 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=51 + - title: Oklahoma House Bill 1933 (2022) + href: https://www.oklegislature.gov/cf_pdf/2021-22%20ENR/hB/HB1933%20ENR.PDF diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml new file mode 100644 index 00000000000..265820c4ca4 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml @@ -0,0 +1,12 @@ +description: Oklahoma disregards this amount of weekly earnings before reducing the partial weekly benefit under the Unemployment Insurance program. + +values: + 1994-07-01: 100 + +metadata: + unit: currency-USD + period: week + label: Oklahoma UI partial benefit earnings disregard + reference: + - title: 40 O.S. §2-105 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml new file mode 100644 index 00000000000..dc18c9b6c3d --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml @@ -0,0 +1,12 @@ +description: Oklahoma uses this divisor on taxable high quarter wages to compute the weekly benefit amount under the Unemployment Insurance program. + +values: + 1980-07-01: 23 + +metadata: + unit: /1 + period: year + label: Oklahoma UI weekly benefit divisor + reference: + - title: 40 O.S. §2-104(A) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml new file mode 100644 index 00000000000..3198b60eca6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml @@ -0,0 +1,20 @@ +description: Oklahoma sets the maximum weekly benefit amount at this amount under the Unemployment Insurance program. + +values: + 2024-01-01: 519 + 2025-01-01: 541 + 2026-01-01: 649 + +metadata: + unit: currency-USD + period: week + label: Oklahoma UI maximum weekly benefit amount + reference: + - title: 40 O.S. §2-104(B) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49 + - title: OESC Claimant Handbook OES-339 (Rev. 05-2025), page 4 + href: https://oklahoma.gov/content/dam/ok/en/oesc/documents/forms/OES-339.pdf#page=4 + - title: OESC Important Numbers for 2025 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2025.pdf#page=1 + - title: OESC Important Numbers for 2026 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml new file mode 100644 index 00000000000..e552cf652d1 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml @@ -0,0 +1,12 @@ +description: Oklahoma sets the minimum weekly benefit amount at this amount under the Unemployment Insurance program. + +values: + 1980-07-01: 16 + +metadata: + unit: currency-USD + period: week + label: Oklahoma UI minimum weekly benefit amount + reference: + - title: 40 O.S. §2-104(A) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49 diff --git a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml index aeec506fd45..2b897853cec 100644 --- a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml +++ b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml @@ -1,15 +1,24 @@ -description: Employer-side unemployment insurance taxable wage base for Oklahoma. +description: Oklahoma sets the annual unemployment insurance taxable wage base at this amount under the Unemployment Insurance program. + values: 0000-01-01: 27_000 + 2025-01-01: 28_200 + 2026-01-01: 25_000 metadata: period: year unit: currency-USD label: Oklahoma unemployment taxable wage base reference: - - title: Oklahoma Statutes Title 40 Section 1-223 - href: https://oksenate.gov/sites/default/files/2022-05/os40.pdf#page=32 - - title: Oklahoma Employment Security Commission important numbers for 2026 + - title: 40 O.S. §1-218 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=42 + - title: 40 O.S. §1-223 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=44 + - title: 40 O.S. §2-207(B) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56 + - title: Oklahoma Employment Security Commission Important Numbers for 2025 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2025.pdf#page=1 + - title: Oklahoma Employment Security Commission Important Numbers for 2026 href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf#page=1 - title: Tax Measures of State Unemployment Insurance Tax Systems, CY 2024 href: https://oui.doleta.gov/unemploy/pdf/sigmeasures/sigmeasuitaxsys24.pdf#page=46 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml new file mode 100644 index 00000000000..29df58d169a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml @@ -0,0 +1,505 @@ +# Edge case tests for Oklahoma Unemployment Insurance (OK UI). +# Boundary conditions for the monetary eligibility tests (§ 2-207), +# the WBA clamp (§ 2-104), the partial-benefit subtraction (§ 2-105), +# the MBA / max_weeks transition (§ 2-106, HB 1933), and the +# defined_for state gate. + +# --- Test A boundary (§ 2-207(A)): taxable >= $1,500 AND total >= 1.5 * HQW --- + +- name: Case 1, Test A taxable wages exactly at $1,500 threshold. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 1_000 + ok_ui_base_period_taxable_wages: 1_500 + ok_ui_base_period_total_wages: 1_500 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A taxable prong: $1,500 >= $1,500 -> passes (>= operator). + # Test A multiplier prong: $1,500 >= 1.5 * $1,000 = $1,500 -> passes (>=). + # Test A: both prongs pass. + ok_ui_meets_high_quarter_test: true + # Test B: total $1,500 < $27,400 (2024 wage base) -> fails. + ok_ui_meets_alternate_wages_test: false + ok_ui_monetarily_eligible: true + +- name: Case 2, Test A taxable wages one dollar below threshold. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 1_000 + ok_ui_base_period_taxable_wages: 1_499 + ok_ui_base_period_total_wages: 1_500 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A taxable prong: $1,499 < $1,500 -> fails. + ok_ui_meets_high_quarter_test: false + # Test B: $1,499 > 0 but total $1,500 < $27,400 -> fails. + ok_ui_meets_alternate_wages_test: false + ok_ui_monetarily_eligible: false + +- name: Case 3, Test A total wages exactly at 1.5x HQW boundary. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 5_000 + ok_ui_base_period_total_wages: 15_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A multiplier prong: $15,000 >= 1.5 * $10,000 = $15,000 -> passes (>= operator). + # Test A taxable prong: $5,000 >= $1,500 -> passes. + ok_ui_meets_high_quarter_test: true + ok_ui_monetarily_eligible: true + +- name: Case 4, Test A total wages one dollar below 1.5x HQW boundary. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 5_000 + ok_ui_base_period_total_wages: 14_999 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A multiplier prong: $14,999 < 1.5 * $10,000 = $15,000 -> fails. + ok_ui_meets_high_quarter_test: false + # Test B: total $14,999 < $27,400 -> fails. + ok_ui_meets_alternate_wages_test: false + ok_ui_monetarily_eligible: false + +# --- Test B boundary (§ 2-207(B)): taxable > 0 AND total >= wage base --- + +- name: Case 5, Test B total wages exactly at 2025 taxable wage base. + period: 2025 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 20_000 + ok_ui_base_period_taxable_wages: 2_000 + ok_ui_base_period_total_wages: 28_200 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: $28,200 < 1.5 * $20,000 = $30,000 -> fails. + ok_ui_meets_high_quarter_test: false + # Test B: taxable $2,000 > $0 AND $28,200 >= $28,200 (2025 wage base) -> passes (>=). + ok_ui_meets_alternate_wages_test: true + ok_ui_monetarily_eligible: true + +- name: Case 6, Test B total wages one dollar below 2025 taxable wage base. + period: 2025 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 20_000 + ok_ui_base_period_taxable_wages: 2_000 + ok_ui_base_period_total_wages: 28_199 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: $28,199 < $30,000 -> fails. + ok_ui_meets_high_quarter_test: false + # Test B: $28,199 < $28,200 -> fails. + ok_ui_meets_alternate_wages_test: false + ok_ui_monetarily_eligible: false + +# --- WBA clamp boundaries (§ 2-104(A): floor(HQW / 23), clamped to [$16, max]) --- + +- name: Case 7, WBA below minimum - HQW $367 clamped up to $16 floor. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 367 + ok_ui_base_period_taxable_wages: 1_500 + ok_ui_base_period_total_wages: 2_250 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($367 / 23) = floor($15.957) = $15 -> below $16 minimum -> clamped to $16. + ok_ui_weekly_benefit_rate: 16 + +- name: Case 8, WBA exactly at minimum - HQW $368 yields $16. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 368 + ok_ui_base_period_taxable_wages: 1_500 + ok_ui_base_period_total_wages: 2_250 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($368 / 23) = floor($16.0) = $16 -> exactly at minimum. + ok_ui_weekly_benefit_rate: 16 + +- name: Case 9, WBA exactly at 2024 maximum - HQW $11,937 yields $519. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 11_937 + ok_ui_base_period_taxable_wages: 11_937 + ok_ui_base_period_total_wages: 30_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # 519 * 23 = $11,937 exactly; floor($11,937 / 23) = $519. + # 2024 max is $519 -> no clamp needed, exactly at boundary. + ok_ui_weekly_benefit_rate: 519 + +- name: Case 10, WBA still at 2024 max - HQW $11,938 yields $519. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 11_938 + ok_ui_base_period_taxable_wages: 11_938 + ok_ui_base_period_total_wages: 30_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($11,938 / 23) = floor($519.043) = $519 -> at 2024 max, no clamp. + ok_ui_weekly_benefit_rate: 519 + +- name: Case 11, WBA clamped down at 2024 max - HQW $11,960 yields $520 raw, clamped to $519. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 11_960 + ok_ui_base_period_taxable_wages: 11_960 + ok_ui_base_period_total_wages: 30_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # 520 * 23 = $11,960 exactly; floor($11,960 / 23) = $520. + # $520 > $519 (2024 max) -> clamped down to $519. + ok_ui_weekly_benefit_rate: 519 + +- name: Case 12, very high HQW clamped to 2025 max $541. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 100_000 + ok_ui_base_period_taxable_wages: 100_000 + ok_ui_base_period_total_wages: 300_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($100,000 / 23) = floor($4,347.83) = $4,347 -> far above $541 (2025 max) -> clamped to $541. + ok_ui_weekly_benefit_rate: 541 + +# --- Zero income / zero weeks --- + +- name: Case 13, all wages zero - both tests fail, no benefit. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 0 + ok_ui_base_period_taxable_wages: 0 + ok_ui_base_period_total_wages: 0 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: $0 < $1,500 -> fails. Test B: $0 not > 0 -> fails. + ok_ui_monetarily_eligible: false + # defined_for gate -> $0. + ok_ui: 0 + +- name: Case 14, eligible but zero weeks unemployed - annual benefit zero. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 0 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_monetarily_eligible: true + # WBA: floor($9,200 / 23) = $400. + ok_ui_weekly_benefit_rate: 400 + # MBA = $400 * 16 = $6,400 (defined regardless of weeks worked). + ok_ui_maximum_benefit_amount: 6_400 + # Annual: min($400 * 0, $6,400) = $0. + ok_ui: 0 + +# --- Partial benefit edge cases (§ 2-105) --- + +- name: Case 15, weekly earnings exactly at $100 disregard - full WBA paid. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 100 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # earnings_reduction = max(0, $100 - $100) = $0; payable = max(0, $400 - 0) = $400. + ok_ui_weekly_payable: 400 + +- name: Case 16, weekly earnings one dollar above disregard - WBA reduced by $1. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 101 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # earnings_reduction = max(0, $101 - $100) = $1; payable = max(0, $400 - $1) = $399. + ok_ui_weekly_payable: 399 + +- name: Case 17, weekly earnings exactly at WBA + disregard - payable zero. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 500 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # earnings_reduction = max(0, $500 - $100) = $400; payable = max(0, $400 - $400) = $0. + ok_ui_weekly_payable: 0 + +- name: Case 18, weekly earnings above WBA + disregard - payable floored at zero. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 501 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # earnings_reduction = max(0, $501 - $100) = $401; raw payable = $400 - $401 = -$1 -> max(0, -1) = $0. + ok_ui_weekly_payable: 0 + +# --- max_weeks transition (§ 2-106, HB 1933): 26 pre-2023, 16 from 2023-01-01 --- + +- name: Case 19, year 2022 - pre-2023 max_weeks of 26. + period: 2022 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + # HQW $6,900 -> floor($6,900 / 23) = $300. + ok_ui_high_quarter_taxable_wages: 6_900 + ok_ui_base_period_taxable_wages: 6_900 + ok_ui_base_period_total_wages: 20_700 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 300 + # 2022 max_weeks = 26; MBA = $300 * 26 = $7,800. + ok_ui_maximum_benefit_amount: 7_800 + +- name: Case 20, year 2024 - post-2023 max_weeks of 16. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + # Same HQW as Case 19 to isolate the max_weeks change. + ok_ui_high_quarter_taxable_wages: 6_900 + ok_ui_base_period_taxable_wages: 6_900 + ok_ui_base_period_total_wages: 20_700 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 300 + # 2024 max_weeks = 16; MBA = $300 * 16 = $4,800. + ok_ui_maximum_benefit_amount: 4_800 + +# --- State gate (defined_for = "ok_ui_monetarily_eligible" with StateCode.OK) --- + +- name: Case 21, non-OK state with otherwise eligible inputs - benefit zeroed. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 11_500 + ok_ui_base_period_taxable_wages: 11_500 + ok_ui_base_period_total_wages: 35_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: TX + output: + people: + person1: + # state_code TX: StateCode.OK gate on upstream variables and the + # ok_ui_monetarily_eligible defined_for cascade returns $0. + ok_ui: 0 + +- name: Case 22, OK state with same inputs as Case 21 - benefit positive. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 11_500 + ok_ui_base_period_taxable_wages: 11_500 + ok_ui_base_period_total_wages: 35_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_monetarily_eligible: true + # WBA: floor($11,500 / 23) = $500; within 2024 [$16, $519] -> $500. + ok_ui_weekly_benefit_rate: 500 + # MBA = $500 * 16 = $8,000; annual = min($500 * 16, $8,000) = $8,000. + ok_ui: 8_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml new file mode 100644 index 00000000000..e134af4cce7 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml @@ -0,0 +1,209 @@ +# Integration tests for Oklahoma Unemployment Insurance (OK UI). +# End-to-end scenarios checking ok_ui together with intermediate variables. +# References: 40 O.S. §§1-202, 1-218, 1-223, 1-231, 2-102, 2-104, 2-105, 2-106, 2-207; +# OESC Claimant Handbook OES-339 (Rev. 05-2025); OESC Important Numbers 2024/2025/2026. + +- name: Case 1, eligible single claimant with mid-range wages in 2024. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 11_500 + ok_ui_base_period_taxable_wages: 11_500 + ok_ui_base_period_total_wages: 35_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $11,500 >= $1,500 (ok); total $35,000 >= 1.5 * $11,500 = $17,250 -> passes. + ok_ui_meets_high_quarter_test: true + ok_ui_monetarily_eligible: true + # WBA: floor($11,500 / 23) = $500; within 2024 [$16, $519] -> $500. + ok_ui_weekly_benefit_rate: 500 + # Earnings $0 -> full WBA paid. + ok_ui_weekly_payable: 500 + # 2024 max_weeks = 16 (post-2023); MBA = $500 * 16 = $8,000. + ok_ui_maximum_benefit_amount: 8_000 + # Annual: min($500 * 16, $8,000) = $8,000. + ok_ui: 8_000 + +- name: Case 2, ineligible claimant - wages too low in 2024. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + ok_ui_high_quarter_taxable_wages: 5_000 + ok_ui_base_period_taxable_wages: 500 + ok_ui_base_period_total_wages: 5_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 12 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $500 < $1,500 -> fails. + ok_ui_meets_high_quarter_test: false + # Test B: total $5,000 < $27,400 (2024 wage base) -> fails. + ok_ui_meets_alternate_wages_test: false + ok_ui_monetarily_eligible: false + # defined_for gate -> $0. + ok_ui: 0 + +- name: Case 3, high earner in 2025 capped at $541 max WBA. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + ok_ui_high_quarter_taxable_wages: 30_000 + ok_ui_base_period_taxable_wages: 30_000 + ok_ui_base_period_total_wages: 90_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $30,000 >= $1,500; total $90,000 >= 1.5 * $30,000 = $45,000 -> passes. + ok_ui_monetarily_eligible: true + # WBA: floor($30,000 / 23) = floor($1,304.35) = $1,304; clamped to $541 (2025 max). + ok_ui_weekly_benefit_rate: 541 + ok_ui_weekly_payable: 541 + # MBA = $541 * 16 = $8,656. + ok_ui_maximum_benefit_amount: 8_656 + # Annual: min($541 * 16, $8,656) = $8,656. + ok_ui: 8_656 + +- name: Case 4, partial benefit week - claimant works part-time. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 32 + # HQW $9,200 -> WBA = $400. + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 200 + weeks_unemployed: 10 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $9,200 >= $1,500; total $30,000 >= 1.5 * $9,200 = $13,800 -> passes. + ok_ui_monetarily_eligible: true + # WBA: floor($9,200 / 23) = $400; within 2025 [$16, $541] -> $400. + ok_ui_weekly_benefit_rate: 400 + # Earnings offset: max(0, $200 - $100) = $100. + # Partial: max(0, $400 - $100) = $300. + ok_ui_weekly_payable: 300 + # MBA = $400 * 16 = $6,400. + ok_ui_maximum_benefit_amount: 6_400 + # Annual: min($300 * 10, $6,400) = min($3,000, $6,400) = $3,000. + ok_ui: 3_000 + +- name: Case 5, pre-2023 regime - 26-week max_weeks doubles MBA. + period: 2022 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 38 + # HQW $6,900 -> WBA = $300. + ok_ui_high_quarter_taxable_wages: 6_900 + ok_ui_base_period_taxable_wages: 6_900 + ok_ui_base_period_total_wages: 20_700 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 26 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $6,900 >= $1,500; total $20,700 >= 1.5 * $6,900 = $10,350 -> passes. + ok_ui_monetarily_eligible: true + # WBA: floor($6,900 / 23) = $300. + ok_ui_weekly_benefit_rate: 300 + ok_ui_weekly_payable: 300 + # Pre-2023 max_weeks = 26; MBA = $300 * 26 = $7,800. + ok_ui_maximum_benefit_amount: 7_800 + # Annual: min($300 * 26, $7,800) = $7,800. + ok_ui: 7_800 + +- name: Case 6, Test B prong - low taxable but high total wages in 2025. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 50 + ok_ui_high_quarter_taxable_wages: 20_000 + ok_ui_base_period_taxable_wages: 2_000 + ok_ui_base_period_total_wages: 28_500 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $2,000 >= $1,500 (ok); total $28,500 < 1.5 * $20,000 = $30,000 -> fails. + ok_ui_meets_high_quarter_test: false + # Test B: taxable $2,000 > $0 (ok); total $28,500 >= $28,200 (2025 wage base) -> passes. + ok_ui_meets_alternate_wages_test: true + ok_ui_monetarily_eligible: true + # WBA: floor($20,000 / 23) = floor($869.57) = $869; clamped to $541 (2025 max). + ok_ui_weekly_benefit_rate: 541 + ok_ui_weekly_payable: 541 + # MBA = $541 * 16 = $8,656. + ok_ui_maximum_benefit_amount: 8_656 + # Annual: min($541 * 16, $8,656) = $8,656. + ok_ui: 8_656 + +- name: Case 7, out-of-state claimant - state gate yields zero benefit. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 11_500 + ok_ui_base_period_taxable_wages: 11_500 + ok_ui_base_period_total_wages: 35_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: TX + output: + people: + person1: + # state_code TX != OK -> defined_for = StateCode.OK gate -> $0. + # Note: intermediate variables (eligibility, WBA, etc.) may still + # compute, but the top-level ok_ui is gated to OK households only. + ok_ui: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui.yaml new file mode 100644 index 00000000000..79bf70b11bc --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui.yaml @@ -0,0 +1,83 @@ +# Tests for Oklahoma UI annual benefit (top-level variable). +# Annual benefit = min(partial_weekly_benefit * weeks_unemployed, MBA). +# Gated by ok_ui_monetarily_eligible (defined_for) and StateCode.OK. +# Reference: 40 O.S. §2-105, §2-106. + +- name: Case 1, eligible claimant - 10 weeks unemployed yields partial of MBA. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + # HQW $9,200 -> WBA = $400 (within 2025 [$16, $541] range). + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 10 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $9,200 >= $1,500 AND total $30,000 >= 1.5 * $9,200 = $13,800 -> passes. + ok_ui_monetarily_eligible: true + ok_ui_weekly_benefit_rate: 400 + ok_ui_weekly_payable: 400 + # MBA = $400 * 16 weeks = $6,400. + ok_ui_maximum_benefit_amount: 6_400 + # Annual = min($400 * 10, $6,400) = min($4,000, $6,400) = $4,000. + ok_ui: 4_000 + +- name: Case 2, eligible claimant - weeks exceed max_weeks - capped at MBA. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 20 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_monetarily_eligible: true + ok_ui_weekly_benefit_rate: 400 + ok_ui_maximum_benefit_amount: 6_400 + # Annual = min($400 * 20, $6,400) = min($8,000, $6,400) = $6,400 (capped at MBA). + ok_ui: 6_400 + +- name: Case 3, monetarily ineligible - zero benefit regardless of weeks. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 1_000 + ok_ui_base_period_total_wages: 12_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $1,000 < $1,500 -> fails. + # Test B: total $12,000 < $28,200 (2025 wage base) -> fails. + ok_ui_monetarily_eligible: false + # defined_for gate -> $0. + ok_ui: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml new file mode 100644 index 00000000000..2a0ea54c2c9 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml @@ -0,0 +1,44 @@ +# Tests for Oklahoma UI maximum benefit amount (40 O.S. §2-106). +# MBA = WBA * max_weeks. +# max_weeks: 26 before 2023-01-01, 16 from 2023-01-01. +# Reference: 40 O.S. §2-106; HB 1933 (2022). + +- name: Case 1, 2024 - WBA $400 yields MBA $6,400 over 16 weeks. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + # HQW $9,200 -> floor($9,200 / 23) = $400 (within 2024 [$16, $519] range). + ok_ui_high_quarter_taxable_wages: 9_200 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # 2024 max_weeks = 16; MBA = $400 * 16 = $6,400. + ok_ui_maximum_benefit_amount: 6_400 + +- name: Case 2, pre-2023 - WBA $300 yields MBA $7,800 over 26 weeks. + period: 2022 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + # HQW $6,900 -> floor($6,900 / 23) = $300. + ok_ui_high_quarter_taxable_wages: 6_900 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 300 + # Pre-2023 max_weeks = 26; MBA = $300 * 26 = $7,800. + ok_ui_maximum_benefit_amount: 7_800 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.yaml new file mode 100644 index 00000000000..f1a9d1cf37c --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.yaml @@ -0,0 +1,65 @@ +# Tests for Oklahoma UI monetary eligibility Test B (40 O.S. §2-207(B)). +# Both conditions must be met: +# 1. Base-period taxable wages > 0. +# 2. Total base-period wages >= annual taxable wage base for the claim year. +# 2025 taxable wage base = $28,200 (gov.states.ok.tax.payroll.unemployment.taxable_wage_base). +# Reference: 40 O.S. §2-207(B); 40 O.S. §1-223. + +- name: Case 1, both prongs pass with minimal taxable and total at wage base. + period: 2025 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 7_050 + ok_ui_base_period_taxable_wages: 1 + ok_ui_base_period_total_wages: 28_200 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Taxable $1 > $0 (passes prong 1). + # Total $28,200 >= $28,200 (2025 wage base) -> passes prong 2. + ok_ui_meets_alternate_wages_test: true + +- name: Case 2, fails taxable wages prong - zero taxable wages. + period: 2025 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 0 + ok_ui_base_period_taxable_wages: 0 + ok_ui_base_period_total_wages: 50_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Taxable $0 is not > $0 -> fails prong 1. + ok_ui_meets_alternate_wages_test: false + +- name: Case 3, fails total-wages prong by one dollar below 2025 wage base. + period: 2025 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 7_000 + ok_ui_base_period_taxable_wages: 1_000 + ok_ui_base_period_total_wages: 28_199 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Taxable $1,000 > 0 (passes prong 1). + # Total $28,199 < $28,200 (2025 wage base) -> fails prong 2. + ok_ui_meets_alternate_wages_test: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.yaml new file mode 100644 index 00000000000..973dce5260f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.yaml @@ -0,0 +1,84 @@ +# Tests for Oklahoma UI monetary eligibility Test A (40 O.S. §2-207(A)). +# Both conditions must be met: +# 1. Base-period taxable wages >= $1,500. +# 2. Total base-period wages >= 1.5 x high-quarter taxable wages. +# Reference: 40 O.S. §2-207(A). + +- name: Case 1, both prongs pass with margin. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 1_500 + ok_ui_base_period_total_wages: 15_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Taxable $1,500 >= $1,500 (passes prong 1). + # Total $15,000 >= 1.5 * $10,000 = $15,000 (passes prong 2). + ok_ui_meets_high_quarter_test: true + +- name: Case 2, fails taxable wages floor by one dollar. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 1_499 + ok_ui_base_period_total_wages: 15_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Taxable $1,499 < $1,500 -> fails prong 1. + ok_ui_meets_high_quarter_test: false + +- name: Case 3, fails 1.5x high-quarter multiplier by one dollar. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 2_000 + ok_ui_base_period_total_wages: 14_999 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Taxable $2,000 >= $1,500 (passes prong 1). + # Total $14,999 < 1.5 * $10,000 = $15,000 -> fails prong 2. + ok_ui_meets_high_quarter_test: false + +- name: Case 4, boundary - taxable exactly at floor and total exactly at 1.5 x HQW. + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 1_500 + ok_ui_base_period_total_wages: 15_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Taxable exactly $1,500 (passes prong 1; >= test). + # Total exactly $15,000 = 1.5 * $10,000 (passes prong 2; >= test). + ok_ui_meets_high_quarter_test: true diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml new file mode 100644 index 00000000000..a51f5b8bd51 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml @@ -0,0 +1,74 @@ +# Tests for Oklahoma UI overall monetary eligibility (40 O.S. §2-207). +# Eligible if Test A OR Test B passes: +# Test A (§2-207(A)): taxable >= $1,500 AND total >= 1.5 x HQW. +# Test B (§2-207(B)): taxable > 0 AND total >= annual taxable wage base. +# Reference: 40 O.S. §2-207. + +- name: Case 1, Test A passes alone (Test B fails on total below wage base). + period: 2024 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 5_000 + ok_ui_base_period_total_wages: 20_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $5,000 >= $1,500 AND $20,000 >= 1.5 * $10,000 = $15,000 -> passes. + # Test B: total $20,000 < $27,400 (2024 wage base) -> fails. + # Overall: A OR B = true. + ok_ui_meets_high_quarter_test: true + ok_ui_meets_alternate_wages_test: false + ok_ui_monetarily_eligible: true + +- name: Case 2, Test B passes alone (Test A fails on 1.5x prong). + period: 2025 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 20_000 + ok_ui_base_period_taxable_wages: 2_000 + ok_ui_base_period_total_wages: 28_500 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $2,000 >= $1,500 (ok); total $28,500 < 1.5 * $20,000 = $30,000 -> fails. + # Test B: taxable $2,000 > $0 (ok); total $28,500 >= $28,200 (2025 wage base) -> passes. + # Overall: A OR B = true. + ok_ui_meets_high_quarter_test: false + ok_ui_meets_alternate_wages_test: true + ok_ui_monetarily_eligible: true + +- name: Case 3, both tests fail. + period: 2025 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 1_000 + ok_ui_base_period_total_wages: 12_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # Test A: taxable $1,000 < $1,500 -> fails. + # Test B: total $12,000 < $28,200 (2025 wage base) -> fails. + # Overall: A OR B = false. + ok_ui_meets_high_quarter_test: false + ok_ui_meets_alternate_wages_test: false + ok_ui_monetarily_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml new file mode 100644 index 00000000000..969d061f63f --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml @@ -0,0 +1,101 @@ +# Tests for Oklahoma UI weekly benefit amount (40 O.S. §2-104(A), §2-102). +# Formula: WBA = clamp(floor(HQW_taxable / 23), [min=$16, max=annual_cap]). +# Annual max WBA: 2024=$519, 2025=$541, 2026=$649. +# Min WBA $16 has been the statutory floor since 1980. +# Reference: 40 O.S. §2-104(A), §2-102; OESC Important Numbers. + +- name: Case 1, handbook example - HQW $14,000 in 2024 clamped to max $519. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 14_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($14,000 / 23) = floor($608.69) = $608. + # $608 > $519 (2024 max) -> clamped to $519. + # Matches OES-339 Rev. 05-2025 page 4 worked example. + ok_ui_weekly_benefit_rate: 519 + +- name: Case 2, low HQW lifted to statutory minimum $16. + period: 2024 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 200 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($200 / 23) = floor($8.70) = $8. + # $8 < $16 -> lifted to $16 minimum. + ok_ui_weekly_benefit_rate: 16 + +- name: Case 3, mid HQW within 2025 range. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($10,000 / 23) = floor($434.78) = $434. + # $16 <= $434 <= $541 (2025 max) -> WBA = $434. + ok_ui_weekly_benefit_rate: 434 + +- name: Case 4, mid HQW within 2026 range. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($10,000 / 23) = $434. + # $16 <= $434 <= $649 (2026 max) -> WBA = $434. + ok_ui_weekly_benefit_rate: 434 + +- name: Case 5, high HQW clamped to 2026 maximum. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + ok_ui_high_quarter_taxable_wages: 20_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($20,000 / 23) = floor($869.57) = $869. + # $869 > $649 (2026 max) -> clamped to $649. + ok_ui_weekly_benefit_rate: 649 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.yaml new file mode 100644 index 00000000000..101e2c51e51 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.yaml @@ -0,0 +1,98 @@ +# Tests for Oklahoma UI partial weekly benefit (40 O.S. §2-105). +# Formula: weekly_payable = max(0, WBA - max(0, weekly_earnings - $100)). +# The first $100 of weekly earnings is disregarded; every dollar above $100 +# reduces WBA dollar-for-dollar; result is floored at $0. +# Reference: 40 O.S. §2-105. + +- name: Case 1, weekly earnings below disregard - full WBA paid. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + # HQW $9,200 -> floor($9,200 / 23) = $400 WBA (within 2025 range). + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 50 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # Earnings $50 < $100 disregard -> earnings_offset = max(0, 50 - 100) = $0. + # Payable = max(0, $400 - $0) = $400. + ok_ui_weekly_payable: 400 + +- name: Case 2, weekly earnings exactly at disregard - full WBA paid. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 100 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # Earnings $100 = $100 disregard -> earnings_offset = max(0, 100 - 100) = $0. + # Payable = max(0, $400 - $0) = $400. + ok_ui_weekly_payable: 400 + +- name: Case 3, weekly earnings above disregard - dollar-for-dollar reduction. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 150 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # Earnings $150 > $100 -> earnings_offset = $150 - $100 = $50. + # Payable = max(0, $400 - $50) = $350. + ok_ui_weekly_payable: 350 + +- name: Case 4, weekly earnings so high payable would be negative - floored at zero. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 + ok_ui_gross_weekly_earnings: 600 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 400 + # Earnings $600 > $100 -> earnings_offset = $600 - $100 = $500. + # Raw payable = $400 - $500 = -$100; max(0, -$100) = $0. + ok_ui_weekly_payable: 0 diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui.py new file mode 100644 index 00000000000..aa008c6e789 --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui.py @@ -0,0 +1,36 @@ +from policyengine_us.model_api import * + + +class ok_ui(Variable): + """Annual Oklahoma Unemployment Insurance benefit. Implements the + monetary eligibility tests (§ 2-207), weekly benefit rate (§ 2-104), + partial benefit subtraction (§ 2-105), and benefit duration cap + (§ 2-106 / § 1-231). + + Not modeled: § 1-202.1 / § 1-202.2 alternative and extended base + periods; § 2-104(B) max-WBA percentage derivation by fund condition + (only the resulting maximum dollar amount is parameterized); § 1-231(A) + claim-volume duration escalation to 20 or 26 weeks; § 2-107 portion- + of-a-week proration; § 2-108 approved training waiver; § 2-202 / + § 2-205.1 able-available-seeking-work; § 2-206 one-week waiting period; + § 2-208 alien-status rules; § 2-109 10x WBA requalification; all + § 2-404 through § 2-422 disqualifications. + """ + + value_type = float + entity = Person + label = "Oklahoma unemployment insurance" + unit = USD + definition_period = YEAR + defined_for = "ok_ui_monetarily_eligible" + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=51", + ) + + def formula(person, period, parameters): + weekly_payable = person("ok_ui_weekly_payable", period) + maximum_benefit_amount = person("ok_ui_maximum_benefit_amount", period) + weeks_unemployed = person("weeks_unemployed", period) + annual_benefit = weekly_payable * weeks_unemployed + return min_(annual_benefit, maximum_benefit_amount) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py new file mode 100644 index 00000000000..e905611f4ec --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ok_ui_base_period_taxable_wages(Variable): + """Sum of taxable wages (capped at the Oklahoma taxable wage base per + quarter) across all four quarters of the base period, per 40 O.S. § 1-223 + and § 1-202. Used in the monetary-eligibility tests in § 2-207(A) and + § 2-207(B). PolicyEngine cannot derive quarterly wages from annual data, + so this is a direct input rather than a computed value; populate via test + fixtures or reform. + """ + + value_type = float + entity = Person + label = "Oklahoma UI base period taxable wages" + unit = USD + definition_period = YEAR + default_value = 0 + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=24", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=44", + ) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py new file mode 100644 index 00000000000..eafcf7b91c4 --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ok_ui_base_period_total_wages(Variable): + """Sum of total (uncapped) gross wages across all four quarters of the + base period, per 40 O.S. § 1-218 and § 1-202. Used in the monetary- + eligibility tests in § 2-207(A) and § 2-207(B). PolicyEngine cannot derive + quarterly wages from annual data, so this is a direct input rather than a + computed value; populate via test fixtures or reform. + """ + + value_type = float + entity = Person + label = "Oklahoma UI base period total wages" + unit = USD + definition_period = YEAR + default_value = 0 + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=24", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=42", + ) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py new file mode 100644 index 00000000000..e8169c18a94 --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class ok_ui_gross_weekly_earnings(Variable): + """Gross earnings during a week of partial unemployment, used to compute + the partial weekly benefit reduction per 40 O.S. § 2-105. Stored at the + annual definition period to match other UI inputs; populate via test + fixtures or reform. + """ + + value_type = float + entity = Person + label = "Oklahoma UI gross weekly earnings" + unit = USD + definition_period = YEAR + default_value = 0 + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50" + ) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_high_quarter_taxable_wages.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_high_quarter_taxable_wages.py new file mode 100644 index 00000000000..86e26658d8e --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_high_quarter_taxable_wages.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ok_ui_high_quarter_taxable_wages(Variable): + """Wages paid in the claimant's highest base-period quarter, capped at the + Oklahoma taxable wage base per quarter. Used as the input to the weekly + benefit amount formula per 40 O.S. § 2-104(A). PolicyEngine cannot derive + quarterly wages from annual data, so this is a direct input rather than a + computed value; populate via test fixtures or reform. + """ + + value_type = float + entity = Person + label = "Oklahoma UI high quarter taxable wages" + unit = USD + definition_period = YEAR + default_value = 0 + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=44", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49", + ) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py new file mode 100644 index 00000000000..c3952b11041 --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py @@ -0,0 +1,24 @@ +from policyengine_us.model_api import * + + +class ok_ui_maximum_benefit_amount(Variable): + value_type = float + entity = Person + label = "Oklahoma UI maximum benefit amount" + unit = USD + definition_period = YEAR + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=48", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=51", + ) + + def formula(person, period, parameters): + # § 2-106 caps benefits in a benefit year. Only the weeks-times-WBR + # prong of the three-prong lesser-of test is modeled; the annual-wage + # and wage-share caps in § 2-106 are not modeled because they depend + # on the state-fund conditional factor that we do not track at + # runtime. + p = parameters(period).gov.states.ok.oesc.unemployment_insurance.mba + weekly_benefit_rate = person("ok_ui_weekly_benefit_rate", period) + return weekly_benefit_rate * p.max_weeks diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py new file mode 100644 index 00000000000..73719d86412 --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class ok_ui_meets_alternate_wages_test(Variable): + value_type = bool + entity = Person + label = "Meets the Oklahoma UI alternate monetary eligibility test" + definition_period = YEAR + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56" + ) + + def formula(person, period, parameters): + base_period_taxable_wages = person("ok_ui_base_period_taxable_wages", period) + base_period_total_wages = person("ok_ui_base_period_total_wages", period) + taxable_wage_base = parameters( + period + ).gov.states.ok.tax.payroll.unemployment.taxable_wage_base + has_taxable_wages = base_period_taxable_wages > 0 + meets_wage_base = base_period_total_wages >= taxable_wage_base + return has_taxable_wages & meets_wage_base diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py new file mode 100644 index 00000000000..a4e832983ea --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ok_ui_meets_high_quarter_test(Variable): + value_type = bool + entity = Person + label = "Meets the Oklahoma UI high-quarter monetary eligibility test" + definition_period = YEAR + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56" + ) + + def formula(person, period, parameters): + p = parameters(period).gov.states.ok.oesc.unemployment_insurance.eligibility + base_period_taxable_wages = person("ok_ui_base_period_taxable_wages", period) + base_period_total_wages = person("ok_ui_base_period_total_wages", period) + high_quarter_taxable_wages = person("ok_ui_high_quarter_taxable_wages", period) + meets_taxable_minimum = base_period_taxable_wages >= p.min_taxable_wages + meets_multiplier = base_period_total_wages >= ( + p.min_total_wages_multiplier * high_quarter_taxable_wages + ) + return meets_taxable_minimum & meets_multiplier diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py new file mode 100644 index 00000000000..7b0f3a9c59c --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py @@ -0,0 +1,17 @@ +from policyengine_us.model_api import * + + +class ok_ui_monetarily_eligible(Variable): + value_type = bool + entity = Person + label = "Monetarily eligible for Oklahoma Unemployment Insurance" + definition_period = YEAR + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56" + ) + + def formula(person, period, parameters): + high_quarter = person("ok_ui_meets_high_quarter_test", period) + alternate = person("ok_ui_meets_alternate_wages_test", period) + return high_quarter | alternate diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py new file mode 100644 index 00000000000..a41299642eb --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ok_ui_weekly_benefit_rate(Variable): + value_type = float + entity = Person + label = "Oklahoma UI weekly benefit rate" + unit = USD + definition_period = YEAR + defined_for = StateCode.OK + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49" + ) + + def formula(person, period, parameters): + # § 2-104(A): WBA = floor(high quarter taxable wages / divisor), + # clamped to the statutory minimum and the annual maximum set under + # § 2-104(B). § 2-102 specifies that fractional results are rounded + # down to the next lower whole dollar. + p = parameters(period).gov.states.ok.oesc.unemployment_insurance.wba + high_quarter_taxable_wages = person("ok_ui_high_quarter_taxable_wages", period) + raw_weekly_benefit_rate = np.floor(high_quarter_taxable_wages / p.divisor) + return min_(max_(raw_weekly_benefit_rate, p.min_amount), p.max_amount) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py new file mode 100644 index 00000000000..7efd266f3ce --- /dev/null +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py @@ -0,0 +1,23 @@ +from policyengine_us.model_api import * + + +class ok_ui_weekly_payable(Variable): + value_type = float + entity = Person + label = "Oklahoma UI weekly payable amount" + unit = USD + definition_period = YEAR + defined_for = "ok_ui_monetarily_eligible" + reference = ( + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50" + ) + + def formula(person, period, parameters): + # § 2-105: weekly payable amount = WBR minus the portion of weekly + # earnings that exceeds the statutory earnings disregard, floored at + # zero. + p = parameters(period).gov.states.ok.oesc.unemployment_insurance.partial + weekly_benefit_rate = person("ok_ui_weekly_benefit_rate", period) + gross_weekly_earnings = person("ok_ui_gross_weekly_earnings", period) + earnings_reduction = max_(gross_weekly_earnings - p.disregard, 0) + return max_(weekly_benefit_rate - earnings_reduction, 0) From dbcb34b4870da77370e3b2f0cbea379d69640a5e Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Tue, 12 May 2026 13:39:44 -0400 Subject: [PATCH 3/7] Review-fix round 1: address critical issues from /review-program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace broken 2025 OESC PDF URL with working OMES PDF + OESC homepage - Fix section citation: §1-218 → §1-201(48) + §1-223 in taxable_wage_base - Add subsection specificity: §2-207(A) → §2-207(A)(1)/(A)(2) - Correct PDF page anchors: divisor/min_amount/max_amount #page=49→50; disregard #page=50→51 - Update stale $27,400 test comments to match actual $27,000 param - Replace 0000-01-01 sentinel with 1980-07-01 in mba/max_weeks - Add trailing comma to make single-element reference tuples valid Co-Authored-By: Claude Opus 4.7 (1M context) --- .../eligibility/min_taxable_wages.yaml | 2 +- .../eligibility/min_total_wages_multiplier.yaml | 2 +- .../ok/oesc/unemployment_insurance/mba/max_weeks.yaml | 2 +- .../ok/oesc/unemployment_insurance/partial/disregard.yaml | 2 +- .../ok/oesc/unemployment_insurance/wba/divisor.yaml | 2 +- .../ok/oesc/unemployment_insurance/wba/max_amount.yaml | 6 +++--- .../ok/oesc/unemployment_insurance/wba/min_amount.yaml | 2 +- .../ok/tax/payroll/unemployment/taxable_wage_base.yaml | 8 ++++---- .../states/ok/oesc/unemployment_insurance/edge_cases.yaml | 6 +++--- .../ok/oesc/unemployment_insurance/integration.yaml | 2 +- .../unemployment_insurance/ok_ui_monetarily_eligible.yaml | 2 +- .../unemployment_insurance/ok_ui_gross_weekly_earnings.py | 2 +- .../ok_ui_meets_alternate_wages_test.py | 2 +- .../ok_ui_meets_high_quarter_test.py | 2 +- .../unemployment_insurance/ok_ui_monetarily_eligible.py | 2 +- .../unemployment_insurance/ok_ui_weekly_benefit_rate.py | 2 +- .../oesc/unemployment_insurance/ok_ui_weekly_payable.py | 2 +- 17 files changed, 24 insertions(+), 24 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml index 9d5366c0245..655a9f9d1d0 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_taxable_wages.yaml @@ -8,5 +8,5 @@ metadata: period: year label: Oklahoma UI minimum taxable base period wages reference: - - title: 40 O.S. §2-207(A) + - title: 40 O.S. §2-207(A)(1) href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml index 81bcccc57d1..2a796aad83a 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml @@ -8,5 +8,5 @@ metadata: period: year label: Oklahoma UI minimum total wages multiplier reference: - - title: 40 O.S. §2-207(A) + - title: 40 O.S. §2-207(A)(2) href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml index 8aeb073b58f..72952e0bb3d 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml @@ -1,7 +1,7 @@ description: Oklahoma limits unemployment compensation benefits to this number of weeks within a benefit year under the Unemployment Insurance program. values: - 0000-01-01: 26 + 1980-07-01: 26 2023-01-01: 16 metadata: diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml index 265820c4ca4..376f12c2813 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/partial/disregard.yaml @@ -9,4 +9,4 @@ metadata: label: Oklahoma UI partial benefit earnings disregard reference: - title: 40 O.S. §2-105 - href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=51 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml index dc18c9b6c3d..121e9932471 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/divisor.yaml @@ -9,4 +9,4 @@ metadata: label: Oklahoma UI weekly benefit divisor reference: - title: 40 O.S. §2-104(A) - href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml index 3198b60eca6..d0983f2107a 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml @@ -11,10 +11,10 @@ metadata: label: Oklahoma UI maximum weekly benefit amount reference: - title: 40 O.S. §2-104(B) - href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50 - title: OESC Claimant Handbook OES-339 (Rev. 05-2025), page 4 href: https://oklahoma.gov/content/dam/ok/en/oesc/documents/forms/OES-339.pdf#page=4 - - title: OESC Important Numbers for 2025 - href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2025.pdf#page=1 + - title: Oklahoma Employment Security Commission (2025 maximum WBA $541 set by OESC Board determination per §2-104(B); no current OESC PDF lists the value — see OES-339 for 2024 history) + href: https://oklahoma.gov/oesc.html - title: OESC Important Numbers for 2026 href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml index e552cf652d1..7ab58a396e7 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/min_amount.yaml @@ -9,4 +9,4 @@ metadata: label: Oklahoma UI minimum weekly benefit amount reference: - title: 40 O.S. §2-104(A) - href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50 diff --git a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml index 2b897853cec..c3e53747689 100644 --- a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml +++ b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml @@ -10,14 +10,14 @@ metadata: unit: currency-USD label: Oklahoma unemployment taxable wage base reference: - - title: 40 O.S. §1-218 - href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=42 + - title: 40 O.S. §1-201(48) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=23 - title: 40 O.S. §1-223 href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=44 - title: 40 O.S. §2-207(B) href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56 - - title: Oklahoma Employment Security Commission Important Numbers for 2025 - href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2025.pdf#page=1 + - title: Oklahoma OMES 2025 Rates and Maximums for FICA and Unemployment + href: https://oklahoma.gov/content/dam/ok/en/omes/documents/2025RatesMaximumsFICAUnemployment.pdf#page=1 - title: Oklahoma Employment Security Commission Important Numbers for 2026 href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf#page=1 - title: Tax Measures of State Unemployment Insurance Tax Systems, CY 2024 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml index 29df58d169a..448b726f318 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml @@ -26,7 +26,7 @@ # Test A multiplier prong: $1,500 >= 1.5 * $1,000 = $1,500 -> passes (>=). # Test A: both prongs pass. ok_ui_meets_high_quarter_test: true - # Test B: total $1,500 < $27,400 (2024 wage base) -> fails. + # Test B: total $1,500 < $27,000 (2024 wage base) -> fails. ok_ui_meets_alternate_wages_test: false ok_ui_monetarily_eligible: true @@ -48,7 +48,7 @@ person1: # Test A taxable prong: $1,499 < $1,500 -> fails. ok_ui_meets_high_quarter_test: false - # Test B: $1,499 > 0 but total $1,500 < $27,400 -> fails. + # Test B: $1,499 > 0 but total $1,500 < $27,000 -> fails. ok_ui_meets_alternate_wages_test: false ok_ui_monetarily_eligible: false @@ -91,7 +91,7 @@ person1: # Test A multiplier prong: $14,999 < 1.5 * $10,000 = $15,000 -> fails. ok_ui_meets_high_quarter_test: false - # Test B: total $14,999 < $27,400 -> fails. + # Test B: total $14,999 < $27,000 -> fails. ok_ui_meets_alternate_wages_test: false ok_ui_monetarily_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml index e134af4cce7..83750aa4486 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml @@ -55,7 +55,7 @@ person1: # Test A: taxable $500 < $1,500 -> fails. ok_ui_meets_high_quarter_test: false - # Test B: total $5,000 < $27,400 (2024 wage base) -> fails. + # Test B: total $5,000 < $27,000 (2024 wage base) -> fails. ok_ui_meets_alternate_wages_test: false ok_ui_monetarily_eligible: false # defined_for gate -> $0. diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml index a51f5b8bd51..08c5f4c8c68 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.yaml @@ -21,7 +21,7 @@ people: person1: # Test A: taxable $5,000 >= $1,500 AND $20,000 >= 1.5 * $10,000 = $15,000 -> passes. - # Test B: total $20,000 < $27,400 (2024 wage base) -> fails. + # Test B: total $20,000 < $27,000 (2024 wage base) -> fails. # Overall: A OR B = true. ok_ui_meets_high_quarter_test: true ok_ui_meets_alternate_wages_test: false diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py index e8169c18a94..748f9479071 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py @@ -16,5 +16,5 @@ class ok_ui_gross_weekly_earnings(Variable): default_value = 0 defined_for = StateCode.OK reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50" + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50", ) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py index 73719d86412..c4e30b7ce6f 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_alternate_wages_test.py @@ -8,7 +8,7 @@ class ok_ui_meets_alternate_wages_test(Variable): definition_period = YEAR defined_for = StateCode.OK reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56" + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56", ) def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py index a4e832983ea..74104cad394 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py @@ -8,7 +8,7 @@ class ok_ui_meets_high_quarter_test(Variable): definition_period = YEAR defined_for = StateCode.OK reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56" + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56", ) def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py index 7b0f3a9c59c..0e931a3566f 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_monetarily_eligible.py @@ -8,7 +8,7 @@ class ok_ui_monetarily_eligible(Variable): definition_period = YEAR defined_for = StateCode.OK reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56" + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56", ) def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py index a41299642eb..5e209ca17da 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py @@ -9,7 +9,7 @@ class ok_ui_weekly_benefit_rate(Variable): definition_period = YEAR defined_for = StateCode.OK reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49" + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=49", ) def formula(person, period, parameters): diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py index 7efd266f3ce..1763d12ef47 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_payable.py @@ -9,7 +9,7 @@ class ok_ui_weekly_payable(Variable): definition_period = YEAR defined_for = "ok_ui_monetarily_eligible" reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50" + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50", ) def formula(person, period, parameters): From 4f08d578fd17dd00c1ecfa6a90b3c8af64ab95a2 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Tue, 12 May 2026 13:48:41 -0400 Subject: [PATCH 4/7] Review-fix round 2: address critical issues from /review-program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change 0000-01-01 sentinel to 2024-01-01 in taxable_wage_base - Replace repealed §1-202 with current §1-201(4) in base-period docstrings - Add §2-207 reference to ok_ui_base_period_total_wages (where "total wages" qualifier comes from) - Update §2-104(B) title in max_amount to clarify OESC Board determination Co-Authored-By: Claude Opus 4.7 (1M context) --- .../oesc/unemployment_insurance/wba/max_amount.yaml | 4 ++-- .../tax/payroll/unemployment/taxable_wage_base.yaml | 2 +- .../ok_ui_base_period_taxable_wages.py | 4 ++-- .../ok_ui_base_period_total_wages.py | 12 +++++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml index d0983f2107a..7edf1764d20 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml @@ -10,11 +10,11 @@ metadata: period: week label: Oklahoma UI maximum weekly benefit amount reference: - - title: 40 O.S. §2-104(B) + - title: 40 O.S. §2-104(B) (OESC Board determines maximum weekly benefit annually) href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50 - title: OESC Claimant Handbook OES-339 (Rev. 05-2025), page 4 href: https://oklahoma.gov/content/dam/ok/en/oesc/documents/forms/OES-339.pdf#page=4 - - title: Oklahoma Employment Security Commission (2025 maximum WBA $541 set by OESC Board determination per §2-104(B); no current OESC PDF lists the value — see OES-339 for 2024 history) + - title: Oklahoma Employment Security Commission href: https://oklahoma.gov/oesc.html - title: OESC Important Numbers for 2026 href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml index c3e53747689..42e3375bd73 100644 --- a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml +++ b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml @@ -1,7 +1,7 @@ description: Oklahoma sets the annual unemployment insurance taxable wage base at this amount under the Unemployment Insurance program. values: - 0000-01-01: 27_000 + 2024-01-01: 27_000 2025-01-01: 28_200 2026-01-01: 25_000 diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py index e905611f4ec..3529d41dc1c 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_taxable_wages.py @@ -4,7 +4,7 @@ class ok_ui_base_period_taxable_wages(Variable): """Sum of taxable wages (capped at the Oklahoma taxable wage base per quarter) across all four quarters of the base period, per 40 O.S. § 1-223 - and § 1-202. Used in the monetary-eligibility tests in § 2-207(A) and + and § 1-201(4). Used in the monetary-eligibility tests in § 2-207(A) and § 2-207(B). PolicyEngine cannot derive quarterly wages from annual data, so this is a direct input rather than a computed value; populate via test fixtures or reform. @@ -18,6 +18,6 @@ class ok_ui_base_period_taxable_wages(Variable): default_value = 0 defined_for = StateCode.OK reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=24", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=20", "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=44", ) diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py index eafcf7b91c4..76554a296bd 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_base_period_total_wages.py @@ -3,10 +3,11 @@ class ok_ui_base_period_total_wages(Variable): """Sum of total (uncapped) gross wages across all four quarters of the - base period, per 40 O.S. § 1-218 and § 1-202. Used in the monetary- - eligibility tests in § 2-207(A) and § 2-207(B). PolicyEngine cannot derive - quarterly wages from annual data, so this is a direct input rather than a - computed value; populate via test fixtures or reform. + base period, per 40 O.S. § 1-218 (wages definition), § 1-201(4) (base + period definition), and § 2-207 (where "total wages" is used). Used in + the monetary-eligibility tests in § 2-207(A) and § 2-207(B). PolicyEngine + cannot derive quarterly wages from annual data, so this is a direct input + rather than a computed value; populate via test fixtures or reform. """ value_type = float @@ -17,6 +18,7 @@ class ok_ui_base_period_total_wages(Variable): default_value = 0 defined_for = StateCode.OK reference = ( - "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=24", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=20", "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=42", + "https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56", ) From 0e6b60779e8c0c1f0f313662513702564fc3d907 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Tue, 12 May 2026 14:04:04 -0400 Subject: [PATCH 5/7] Add lessons from Oklahoma UI implementation Co-Authored-By: Claude Opus 4.7 (1M context) --- lessons/agent-lessons.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 lessons/agent-lessons.md diff --git a/lessons/agent-lessons.md b/lessons/agent-lessons.md new file mode 100644 index 00000000000..aedba4661a2 --- /dev/null +++ b/lessons/agent-lessons.md @@ -0,0 +1,23 @@ +# Agent Lessons Learned + +Accumulated from /encode-policy-v2 and /backdate-program runs across all contributors. +Loaded by implementation agents on future runs. + +## New Lessons from Oklahoma UI (2026-05-12) + +### PARAMETER +- Verify every parameter value against authoritative source PDFs before committing; do not let inferred or rounded values reach the YAML files. +- Keep parameter values and any test/comment references to those values in sync — when a value changes, grep for the old number across params, tests, and docstrings in one sweep. +- Reserve sentinel `0000-01-01` effective dates for parameters that genuinely have no historical variation; whenever the value reflects a real first-year-applicable date, use the actual effective date so future audits can trace it. +- When citing a statute that delegates the actual value to an agency (e.g. board-determined annual rates), put the delegating statute in the reference title rather than relying on a homepage URL that does not display the value. + +### REFERENCE +- A single-URL `reference` written as `(string)` is a parenthesized string, not a tuple — write `(string,)` with a trailing comma (or drop parens entirely) to match the multi-reference convention. +- PDF `#page=` anchors should target the file page that contains the cited value or operative text, not the table-of-contents or heading-only page; off-by-one is the common failure mode. +- Statutory citations should be as specific as the value warrants — cite `§X-XXX(A)(1)` when the floor lives in that subsection rather than the broader `§X-XXX(A)`. +- When a cited code section has been repealed, replace the citation with the active replacement section (e.g. updated definitions section) and update the page anchor accordingly; do not leave repealed-section URLs in active references. +- Verify every reference URL actually resolves (no 404s) before merge; keep an alternate authoritative source (e.g. companion agency PDF, statutory text) ready when one URL breaks. + +### WORKFLOW +- When parallel agents produce paired artifacts (variables + tests, params + variables), give each agent the same canonical variable-name and parameter-name list so the files line up — do not let one agent follow the spec and another follow the prompt independently. +- Before approving a new program, audit every parameter value against a manifest of source PDFs; do not rely solely on the implementer's claim that values match. From c12f8a48c6c63e91e566e08d0d05dc639e6e6356 Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Tue, 12 May 2026 14:27:54 -0400 Subject: [PATCH 6/7] Fix Oklahoma UI maximum benefit cap --- lessons/agent-lessons.md | 23 ---------------- .../mba/base_period_wages_share.yaml | 22 +++++++++++++++ .../mba/max_amount.yaml | 26 ++++++++++++++++++ .../wba/max_amount.yaml | 10 +++++++ .../unemployment/taxable_wage_base.yaml | 8 ++++++ .../unemployment_insurance/edge_cases.yaml | 27 ++++++++++++++++++- .../ok_ui_maximum_benefit_amount.yaml | 25 ++++++++++++++++- .../ok_ui_weekly_benefit_rate.yaml | 21 ++++++++++++++- .../ok_ui_maximum_benefit_amount.py | 14 +++++----- 9 files changed, 144 insertions(+), 32 deletions(-) delete mode 100644 lessons/agent-lessons.md create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/base_period_wages_share.yaml create mode 100644 policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_amount.yaml diff --git a/lessons/agent-lessons.md b/lessons/agent-lessons.md deleted file mode 100644 index aedba4661a2..00000000000 --- a/lessons/agent-lessons.md +++ /dev/null @@ -1,23 +0,0 @@ -# Agent Lessons Learned - -Accumulated from /encode-policy-v2 and /backdate-program runs across all contributors. -Loaded by implementation agents on future runs. - -## New Lessons from Oklahoma UI (2026-05-12) - -### PARAMETER -- Verify every parameter value against authoritative source PDFs before committing; do not let inferred or rounded values reach the YAML files. -- Keep parameter values and any test/comment references to those values in sync — when a value changes, grep for the old number across params, tests, and docstrings in one sweep. -- Reserve sentinel `0000-01-01` effective dates for parameters that genuinely have no historical variation; whenever the value reflects a real first-year-applicable date, use the actual effective date so future audits can trace it. -- When citing a statute that delegates the actual value to an agency (e.g. board-determined annual rates), put the delegating statute in the reference title rather than relying on a homepage URL that does not display the value. - -### REFERENCE -- A single-URL `reference` written as `(string)` is a parenthesized string, not a tuple — write `(string,)` with a trailing comma (or drop parens entirely) to match the multi-reference convention. -- PDF `#page=` anchors should target the file page that contains the cited value or operative text, not the table-of-contents or heading-only page; off-by-one is the common failure mode. -- Statutory citations should be as specific as the value warrants — cite `§X-XXX(A)(1)` when the floor lives in that subsection rather than the broader `§X-XXX(A)`. -- When a cited code section has been repealed, replace the citation with the active replacement section (e.g. updated definitions section) and update the page anchor accordingly; do not leave repealed-section URLs in active references. -- Verify every reference URL actually resolves (no 404s) before merge; keep an alternate authoritative source (e.g. companion agency PDF, statutory text) ready when one URL breaks. - -### WORKFLOW -- When parallel agents produce paired artifacts (variables + tests, params + variables), give each agent the same canonical variable-name and parameter-name list so the files line up — do not let one agent follow the spec and another follow the prompt independently. -- Before approving a new program, audit every parameter value against a manifest of source PDFs; do not rely solely on the implementer's claim that values match. diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/base_period_wages_share.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/base_period_wages_share.yaml new file mode 100644 index 00000000000..bb7dc88a817 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/base_period_wages_share.yaml @@ -0,0 +1,22 @@ +description: Oklahoma limits unemployment compensation benefits to this share of base period wages under the Unemployment Insurance program. + +values: + 1980-07-01: 1 + 2023-01-01: 0.4 + 2026-01-01: 0.475 + +metadata: + unit: /1 + period: year + label: Oklahoma UI maximum benefit base period wages share + reference: + - title: 40 O.S. §2-106(3) + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=51 + - title: OESC Important Numbers for 2023 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2023.pdf#page=1 + - title: OESC Important Numbers for 2024 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2024.pdf#page=1 + - title: OESC Important Numbers for 2025 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2025.pdf#page=1 + - title: OESC Important Numbers for 2026 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_amount.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_amount.yaml new file mode 100644 index 00000000000..1d520e18df8 --- /dev/null +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_amount.yaml @@ -0,0 +1,26 @@ +description: Oklahoma limits unemployment compensation benefits to this amount within a benefit year under the Unemployment Insurance program. + +values: + 2022-01-01: 9_900 + 2023-01-01: 7_888 + 2024-01-01: 8_304 + 2025-01-01: 8_656 + 2026-01-01: 10_384 + +metadata: + unit: currency-USD + period: year + label: Oklahoma UI maximum benefit amount + reference: + - title: 40 O.S. §2-106 + href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=51 + - title: Oklahoma UI Tax Rates by Industry, Size, and County, 2021, page 2 + href: https://www.oklahoma.gov/content/dam/ok/en/oesc/documents/labor-market/publications/special-reports/oklahoma-ui-tax-rates-industry-size-county-2021.pdf#page=2 + - title: OESC Important Numbers for 2023 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2023.pdf#page=1 + - title: OESC Important Numbers for 2024 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2024.pdf#page=1 + - title: OESC Important Numbers for 2025 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2025.pdf#page=1 + - title: OESC Important Numbers for 2026 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf#page=1 diff --git a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml index 7edf1764d20..d52e11fe3d6 100644 --- a/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml +++ b/policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml @@ -1,6 +1,8 @@ description: Oklahoma sets the maximum weekly benefit amount at this amount under the Unemployment Insurance program. values: + 2022-01-01: 476 + 2023-01-01: 493 2024-01-01: 519 2025-01-01: 541 2026-01-01: 649 @@ -12,6 +14,14 @@ metadata: reference: - title: 40 O.S. §2-104(B) (OESC Board determines maximum weekly benefit annually) href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=50 + - title: Oklahoma UI Tax Rates by Industry, Size, and County, 2021, page 2 + href: https://www.oklahoma.gov/content/dam/ok/en/oesc/documents/labor-market/publications/special-reports/oklahoma-ui-tax-rates-industry-size-county-2021.pdf#page=2 + - title: OESC Important Numbers for 2023 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2023.pdf#page=1 + - title: OESC Important Numbers for 2024 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2024.pdf#page=1 + - title: OESC Important Numbers for 2025 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2025.pdf#page=1 - title: OESC Claimant Handbook OES-339 (Rev. 05-2025), page 4 href: https://oklahoma.gov/content/dam/ok/en/oesc/documents/forms/OES-339.pdf#page=4 - title: Oklahoma Employment Security Commission diff --git a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml index 42e3375bd73..8aacbe0b4ae 100644 --- a/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml +++ b/policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml @@ -1,6 +1,8 @@ description: Oklahoma sets the annual unemployment insurance taxable wage base at this amount under the Unemployment Insurance program. values: + 2022-01-01: 24_800 + 2023-01-01: 25_700 2024-01-01: 27_000 2025-01-01: 28_200 2026-01-01: 25_000 @@ -16,6 +18,12 @@ metadata: href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=44 - title: 40 O.S. §2-207(B) href: https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf#page=56 + - title: Oklahoma UI Tax Rates by Industry, Size, and County, 2021, page 2 + href: https://www.oklahoma.gov/content/dam/ok/en/oesc/documents/labor-market/publications/special-reports/oklahoma-ui-tax-rates-industry-size-county-2021.pdf#page=2 + - title: OESC Important Numbers for 2023 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2023.pdf#page=1 + - title: OESC Important Numbers for 2024 + href: https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2024.pdf#page=1 - title: Oklahoma OMES 2025 Rates and Maximums for FICA and Unemployment href: https://oklahoma.gov/content/dam/ok/en/omes/documents/2025RatesMaximumsFICAUnemployment.pdf#page=1 - title: Oklahoma Employment Security Commission Important Numbers for 2026 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml index 448b726f318..6ec94da98c9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml @@ -1,7 +1,7 @@ # Edge case tests for Oklahoma Unemployment Insurance (OK UI). # Boundary conditions for the monetary eligibility tests (§ 2-207), # the WBA clamp (§ 2-104), the partial-benefit subtraction (§ 2-105), -# the MBA / max_weeks transition (§ 2-106, HB 1933), and the +# the MBA lesser-of caps / max_weeks transition (§ 2-106, HB 1933), and the # defined_for state gate. # --- Test A boundary (§ 2-207(A)): taxable >= $1,500 AND total >= 1.5 * HQW --- @@ -503,3 +503,28 @@ ok_ui_weekly_benefit_rate: 500 # MBA = $500 * 16 = $8,000; annual = min($500 * 16, $8,000) = $8,000. ok_ui: 8_000 + +- name: Case 23, base-period wages share caps annual benefit. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_taxable_wages: 10_000 + ok_ui_base_period_total_wages: 15_000 + ok_ui_gross_weekly_earnings: 0 + weeks_unemployed: 16 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_monetarily_eligible: true + ok_ui_weekly_benefit_rate: 434 + # Lesser of $434 * 16 = $6,944, statewide $8,656, and 40% * $15,000 = $6,000. + ok_ui_maximum_benefit_amount: 6_000 + ok_ui: 6_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml index 2a0ea54c2c9..ad503f630d9 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml @@ -1,5 +1,5 @@ # Tests for Oklahoma UI maximum benefit amount (40 O.S. §2-106). -# MBA = WBA * max_weeks. +# MBA = min(WBA * max_weeks, statewide max benefit amount, base-period wages share cap). # max_weeks: 26 before 2023-01-01, 16 from 2023-01-01. # Reference: 40 O.S. §2-106; HB 1933 (2022). @@ -12,6 +12,7 @@ age: 35 # HQW $9,200 -> floor($9,200 / 23) = $400 (within 2024 [$16, $519] range). ok_ui_high_quarter_taxable_wages: 9_200 + ok_ui_base_period_total_wages: 30_000 households: household: members: [person1] @@ -32,6 +33,7 @@ age: 35 # HQW $6,900 -> floor($6,900 / 23) = $300. ok_ui_high_quarter_taxable_wages: 6_900 + ok_ui_base_period_total_wages: 20_700 households: household: members: [person1] @@ -42,3 +44,24 @@ ok_ui_weekly_benefit_rate: 300 # Pre-2023 max_weeks = 26; MBA = $300 * 26 = $7,800. ok_ui_maximum_benefit_amount: 7_800 + +- name: Case 3, 2025 - base-period wages share caps marginal Test A claimant. + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + # HQW $10,000 -> floor($10,000 / 23) = $434. + ok_ui_high_quarter_taxable_wages: 10_000 + ok_ui_base_period_total_wages: 15_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + ok_ui_weekly_benefit_rate: 434 + # Lesser of $434 * 16 = $6,944, statewide $8,656, and 40% * $15,000 = $6,000. + ok_ui_maximum_benefit_amount: 6_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml index 969d061f63f..abb3d5247eb 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.yaml @@ -1,6 +1,6 @@ # Tests for Oklahoma UI weekly benefit amount (40 O.S. §2-104(A), §2-102). # Formula: WBA = clamp(floor(HQW_taxable / 23), [min=$16, max=annual_cap]). -# Annual max WBA: 2024=$519, 2025=$541, 2026=$649. +# Annual max WBA: 2022=$476, 2023=$493, 2024=$519, 2025=$541, 2026=$649. # Min WBA $16 has been the statutory floor since 1980. # Reference: 40 O.S. §2-104(A), §2-102; OESC Important Numbers. @@ -99,3 +99,22 @@ # floor($20,000 / 23) = floor($869.57) = $869. # $869 > $649 (2026 max) -> clamped to $649. ok_ui_weekly_benefit_rate: 649 + +- name: Case 6, high HQW clamped to 2022 maximum. + period: 2022 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + ok_ui_high_quarter_taxable_wages: 20_000 + households: + household: + members: [person1] + state_code: OK + output: + people: + person1: + # floor($20,000 / 23) = floor($869.57) = $869. + # $869 > $476 (2022 max) -> clamped to $476. + ok_ui_weekly_benefit_rate: 476 diff --git a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py index c3952b11041..e9e238918ca 100644 --- a/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py +++ b/policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py @@ -14,11 +14,13 @@ class ok_ui_maximum_benefit_amount(Variable): ) def formula(person, period, parameters): - # § 2-106 caps benefits in a benefit year. Only the weeks-times-WBR - # prong of the three-prong lesser-of test is modeled; the annual-wage - # and wage-share caps in § 2-106 are not modeled because they depend - # on the state-fund conditional factor that we do not track at - # runtime. + # § 2-106 caps benefits in a benefit year at the lesser of the + # duration cap, the statewide maximum benefit amount, and the + # applicable share of base-period wages. p = parameters(period).gov.states.ok.oesc.unemployment_insurance.mba weekly_benefit_rate = person("ok_ui_weekly_benefit_rate", period) - return weekly_benefit_rate * p.max_weeks + base_period_total_wages = person("ok_ui_base_period_total_wages", period) + return min_( + min_(weekly_benefit_rate * p.max_weeks, p.max_amount), + base_period_total_wages * p.base_period_wages_share, + ) From 6273dd51e4ef9b368f3213e200fe8d96b538b0fa Mon Sep 17 00:00:00 2001 From: Daphne Hansell <128793799+daphnehanse11@users.noreply.github.com> Date: Thu, 14 May 2026 10:53:16 -0400 Subject: [PATCH 7/7] Register Oklahoma UI program --- policyengine_us/programs.yaml | 11 +++++++++++ .../ok/oesc/unemployment_insurance/integration.yaml | 1 + .../variables/gov/states/unemployment_compensation.py | 1 + 3 files changed, 13 insertions(+) diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 76b5377b5f3..a52c5c18de5 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1126,6 +1126,17 @@ programs: variable: ny_drive_clean_rebate parameter_prefix: gov.states.ny.nyserda.drive_clean + - id: ok_ui + name: Oklahoma UI + full_name: Oklahoma Unemployment Insurance + category: Benefits + agency: Oklahoma Employment Security Commission + status: complete + coverage: OK + variable: ok_ui + parameter_prefix: gov.states.ok.oesc.unemployment_insurance + verified_years: "2022-2026" + - id: tx_fpp_benefit name: Texas FPP full_name: Texas Family Planning Program diff --git a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml index 83750aa4486..589cf24b50c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml @@ -33,6 +33,7 @@ ok_ui_maximum_benefit_amount: 8_000 # Annual: min($500 * 16, $8,000) = $8,000. ok_ui: 8_000 + unemployment_compensation: 8_000 - name: Case 2, ineligible claimant - wages too low in 2024. period: 2024 diff --git a/policyengine_us/variables/gov/states/unemployment_compensation.py b/policyengine_us/variables/gov/states/unemployment_compensation.py index 0857864ab17..2bdaeeac571 100644 --- a/policyengine_us/variables/gov/states/unemployment_compensation.py +++ b/policyengine_us/variables/gov/states/unemployment_compensation.py @@ -9,3 +9,4 @@ class unemployment_compensation(Variable): documentation = "Income from unemployment compensation programs." definition_period = YEAR uprating = "calibration.gov.irs.soi.unemployment_compensation" + adds = ["ok_ui"]