feat: OPPS rules CY2014-2026 + fixed download script (refs #264, #266)
Some checks failed
Infra CI / zotero (push) Failing after 0s
Infra CI / docs (push) Failing after 0s
Infra CI / api (push) Failing after 0s
Infra CI / mc (push) Failing after 0s
CI / skinny-install (aco) (push) Failing after 4m58s
CI / skinny-install (api) (push) Failing after 0s
CI / skinny-install (bcda) (push) Failing after 0s
CI / skinny-install (bib) (push) Failing after 0s
CI / skinny-install (bls) (push) Failing after 0s
CI / skinny-install (ccw) (push) Failing after 0s
CI / skinny-install (cli) (push) Failing after 0s
CI / skinny-install (cms) (push) Failing after 0s
CI / skinny-install (conf) (push) Failing after 0s
CI / skinny-install (perf) (push) Failing after 0s
CI / skinny-install (pfs) (push) Failing after 0s
CI / skinny-install (rex) (push) Failing after 0s
Deploy / build-scan-report (push) Failing after 0s
Infra CI / notebooks (push) Failing after 0s
CI / lint-test (push) Failing after 5m27s
Some checks failed
Infra CI / zotero (push) Failing after 0s
Infra CI / docs (push) Failing after 0s
Infra CI / api (push) Failing after 0s
Infra CI / mc (push) Failing after 0s
CI / skinny-install (aco) (push) Failing after 4m58s
CI / skinny-install (api) (push) Failing after 0s
CI / skinny-install (bcda) (push) Failing after 0s
CI / skinny-install (bib) (push) Failing after 0s
CI / skinny-install (bls) (push) Failing after 0s
CI / skinny-install (ccw) (push) Failing after 0s
CI / skinny-install (cli) (push) Failing after 0s
CI / skinny-install (cms) (push) Failing after 0s
CI / skinny-install (conf) (push) Failing after 0s
CI / skinny-install (perf) (push) Failing after 0s
CI / skinny-install (pfs) (push) Failing after 0s
CI / skinny-install (rex) (push) Failing after 0s
Deploy / build-scan-report (push) Failing after 0s
Infra CI / notebooks (push) Failing after 0s
CI / lint-test (push) Failing after 5m27s
Rules (src/opps/rules/__init__.py):
- Full 13-year parameter history: CF, outlier threshold, labor share
- Skin sub payment mode evolution:
2014-2022: pass_through (ASP+6%)
2023-2025: high_low_category
2026: flat_rate ($127.28/cm², C5271-C5278)
- FR citations, CMS rule IDs, year-specific notes
- Pydantic RuleYear model matching PFS pattern
Download script fixed:
- Uses correct CMS URLs: {year}-nfrm-opps-addenda.zip (CY2021-2026)
- Pre-2021 files purged from CMS site (noted for Wayback recovery)
- Supporting files (cost stats, impacts) for CY2026
This commit is contained in:
@@ -27,102 +27,30 @@ USER_AGENT = "stack-opps-ingest/1.0"
|
||||
# ---------------------------------------------------------------------------
|
||||
# CMS OPPS download URLs by year
|
||||
# ---------------------------------------------------------------------------
|
||||
# These are the canonical download page URLs for each year's addenda.
|
||||
# CMS reorganizes URLs periodically; these are current as of March 2026.
|
||||
# CMS publishes combined addenda ZIPs starting ~CY2021 at:
|
||||
# https://www.cms.gov/files/zip/{year}-nfrm-opps-addenda.zip
|
||||
#
|
||||
# Pre-2021 files were purged from cms.gov during the 2023 site restructure.
|
||||
# They may be recoverable from the Wayback Machine. Filed as a TODO.
|
||||
|
||||
OPPS_SOURCES: list[dict[str, str]] = [
|
||||
{
|
||||
"year": "2026",
|
||||
"addendum_a": "https://www.cms.gov/files/zip/cy2026-opps-final-rule-addendum-a.zip",
|
||||
"addendum_b": "https://www.cms.gov/files/zip/cy2026-opps-final-rule-addendum-b.zip",
|
||||
"wage_index": "https://www.cms.gov/files/zip/cy2026-opps-final-rule-wage-index.zip",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2025/11/20/2025-23371/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
OPPS_ADDENDA_URLS: dict[str, str] = {
|
||||
"2026": "https://www.cms.gov/files/zip/2026-nfrm-opps-addenda.zip",
|
||||
"2025": "https://www.cms.gov/files/zip/2025-nfrm-opps-addenda.zip",
|
||||
"2024": "https://www.cms.gov/files/zip/2024-nfrm-opps-addenda.zip",
|
||||
"2023": "https://www.cms.gov/files/zip/2023-nfrm-opps-addenda.zip",
|
||||
"2022": "https://www.cms.gov/files/zip/2022-nfrm-opps-addenda.zip",
|
||||
"2021": "https://www.cms.gov/files/zip/2021-nfrm-opps-addenda.zip",
|
||||
# Pre-2021: purged from CMS. Need Wayback Machine recovery.
|
||||
}
|
||||
|
||||
# Supporting files (cost stats, impacts, etc.)
|
||||
OPPS_SUPPORTING_URLS: dict[str, dict[str, str]] = {
|
||||
"2026": {
|
||||
"cost_stats": "https://www.cms.gov/files/zip/2026-nfrm-opps-cost-statistics-files.zip",
|
||||
"impacts": "https://www.cms.gov/files/zip/2026-nfrm-opps-facility-specific-impacts.zip",
|
||||
"2x_rule": "https://www.cms.gov/files/zip/2026-nfrm-opps-data-addendum-b-2-times-rule.zip",
|
||||
},
|
||||
{
|
||||
"year": "2025",
|
||||
"addendum_a": "https://www.cms.gov/files/zip/cy2025-opps-final-rule-addendum-a.zip",
|
||||
"addendum_b": "https://www.cms.gov/files/zip/cy2025-opps-final-rule-addendum-b.zip",
|
||||
"wage_index": "https://www.cms.gov/files/zip/cy2025-opps-final-rule-wage-index.zip",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2024/11/18/2024-25518/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2024",
|
||||
"addendum_a": "https://www.cms.gov/files/zip/cy2024-opps-final-rule-addendum-a.zip",
|
||||
"addendum_b": "https://www.cms.gov/files/zip/cy2024-opps-final-rule-addendum-b.zip",
|
||||
"wage_index": "https://www.cms.gov/files/zip/cy2024-opps-final-rule-wage-index.zip",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2023/11/22/2023-24293/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2023",
|
||||
"addendum_a": "https://www.cms.gov/files/zip/cy2023-opps-final-rule-addendum-a.zip",
|
||||
"addendum_b": "https://www.cms.gov/files/zip/cy2023-opps-final-rule-addendum-b.zip",
|
||||
"wage_index": "https://www.cms.gov/files/zip/cy2023-opps-final-rule-wage-index.zip",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2022/11/23/2022-23918/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2022",
|
||||
"addendum_a": "https://www.cms.gov/files/zip/cy2022-opps-final-rule-addendum-a.zip",
|
||||
"addendum_b": "https://www.cms.gov/files/zip/cy2022-opps-final-rule-addendum-b.zip",
|
||||
"wage_index": "https://www.cms.gov/files/zip/cy2022-opps-final-rule-wage-index.zip",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2021/11/16/2021-24011/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2021",
|
||||
"addendum_a": "https://www.cms.gov/files/zip/cy2021-opps-final-rule-addendum-a.zip",
|
||||
"addendum_b": "https://www.cms.gov/files/zip/cy2021-opps-final-rule-addendum-b.zip",
|
||||
"wage_index": "https://www.cms.gov/files/zip/cy2021-opps-final-rule-wage-index.zip",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2020/12/29/2020-26819/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2020",
|
||||
"addendum_a": "https://www.cms.gov/files/zip/cy2020-opps-final-rule-addendum-a.zip",
|
||||
"addendum_b": "https://www.cms.gov/files/zip/cy2020-opps-final-rule-addendum-b.zip",
|
||||
"wage_index": "https://www.cms.gov/files/zip/cy2020-opps-final-rule-wage-index.zip",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2019/11/12/2019-24138/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2019",
|
||||
"addendum_a": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1695-FC-2019-OPPS-FR-Addnda-A.zip",
|
||||
"addendum_b": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1695-FC-2019-OPPS-FR-Addnda-B.zip",
|
||||
"wage_index": "",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2018/11/21/2018-24243/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2018",
|
||||
"addendum_a": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1678-FC-2018-OPPS-FR-Addnda-A.zip",
|
||||
"addendum_b": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1678-FC-2018-OPPS-FR-Addnda-B.zip",
|
||||
"wage_index": "",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2017/11/13/2017-23932/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2017",
|
||||
"addendum_a": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1656-FC-2017-OPPS-FR-Addnda-A.zip",
|
||||
"addendum_b": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1656-FC-2017-OPPS-FR-Addnda-B.zip",
|
||||
"wage_index": "",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2016/11/14/2016-26515/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2016",
|
||||
"addendum_a": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1633-FC-2016-OPPS-FR-Addnda-A.zip",
|
||||
"addendum_b": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1633-FC-2016-OPPS-FR-Addnda-B.zip",
|
||||
"wage_index": "",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2015/11/13/2015-28005/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2015",
|
||||
"addendum_a": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1613-FC-2015-OPPS-FR-Addnda-A.zip",
|
||||
"addendum_b": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1613-FC-2015-OPPS-FR-Addnda-B.zip",
|
||||
"wage_index": "",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2014/11/10/2014-26146/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
{
|
||||
"year": "2014",
|
||||
"addendum_a": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1601-FC-2014-OPPS-FR-Addnda-A.zip",
|
||||
"addendum_b": "https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalOutpatientPPS/Downloads/CMS-1601-FC-2014-OPPS-FR-Addnda-B.zip",
|
||||
"wage_index": "",
|
||||
"rule_fr": "https://www.federalregister.gov/documents/2013/12/10/2013-28737/medicare-program-changes-to-the-hospital-outpatient-prospective-payment-and-ambulatory-surgical-center",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def download_file(url: str, dest: Path) -> bool:
|
||||
@@ -154,44 +82,48 @@ def main() -> None:
|
||||
|
||||
OPPS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
sources = OPPS_SOURCES
|
||||
urls = OPPS_ADDENDA_URLS
|
||||
if args.year:
|
||||
sources = [s for s in sources if s["year"] == args.year]
|
||||
if not sources:
|
||||
print(f"No sources defined for year {args.year}")
|
||||
return
|
||||
urls = {k: v for k, v in urls.items() if k == args.year}
|
||||
|
||||
total = 0
|
||||
downloaded = 0
|
||||
|
||||
for src in sources:
|
||||
year = src["year"]
|
||||
for year, url in sorted(urls.items()):
|
||||
year_dir = OPPS_DIR / year
|
||||
year_dir.mkdir(exist_ok=True)
|
||||
|
||||
print(f"\n--- CY{year} ---")
|
||||
total += 1
|
||||
dest = year_dir / f"opps_{year}_addenda.zip"
|
||||
if download_file(url, dest):
|
||||
downloaded += 1
|
||||
time.sleep(0.5)
|
||||
|
||||
for file_type in ["addendum_a", "addendum_b", "wage_index"]:
|
||||
url = src.get(file_type, "")
|
||||
if not url:
|
||||
continue
|
||||
# Supporting files (if defined)
|
||||
for name, surl in OPPS_SUPPORTING_URLS.get(year, {}).items():
|
||||
total += 1
|
||||
fname = f"opps_{year}_{file_type}.zip"
|
||||
if download_file(url, year_dir / fname):
|
||||
sdest = year_dir / f"opps_{year}_{name}.zip"
|
||||
if download_file(surl, sdest):
|
||||
downloaded += 1
|
||||
time.sleep(0.5)
|
||||
|
||||
print(f"\n{'=' * 50}")
|
||||
print(f"Downloaded: {downloaded}/{total} files")
|
||||
print(f"Location: {OPPS_DIR}")
|
||||
if set(OPPS_ADDENDA_URLS) != set(str(y) for y in range(2014, 2027)):
|
||||
missing = sorted(set(str(y) for y in range(2014, 2027)) - set(OPPS_ADDENDA_URLS))
|
||||
print(f"\nMissing years (purged from CMS): {', '.join(missing)}")
|
||||
print(" These may be recoverable from the Wayback Machine.")
|
||||
|
||||
# List what we have
|
||||
print("\nInventory:")
|
||||
for year_dir in sorted(OPPS_DIR.iterdir()):
|
||||
if year_dir.is_dir():
|
||||
files = list(year_dir.glob("*.zip"))
|
||||
print(f" {year_dir.name}: {len(files)} files "
|
||||
f"({sum(f.stat().st_size for f in files) / 1024 / 1024:.1f} MB)")
|
||||
if files:
|
||||
total_size = sum(f.stat().st_size for f in files)
|
||||
print(f" {year_dir.name}: {len(files)} files "
|
||||
f"({total_size / 1024 / 1024:.1f} MB)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,82 +1,199 @@
|
||||
"""OPPS annual rule parameters.
|
||||
"""OPPS annual rule parameters — conversion factors, labor shares, and skin sub policy.
|
||||
|
||||
Conversion factors, labor shares, packaging thresholds, and
|
||||
skin substitute payment category definitions by calendar year.
|
||||
Each calendar year's OPPS/ASC Final Rule sets the parameters that
|
||||
determine hospital outpatient payment. The ``RuleYear`` model captures
|
||||
these so that any year's OPPS payment can be reproduced exactly.
|
||||
|
||||
Sources: CMS OPPS/ASC Final Rules, Federal Register.
|
||||
https://www.cms.gov/medicare/payment/prospective-payment-systems/hospital-outpatient
|
||||
|
||||
Usage::
|
||||
|
||||
from opps.rules import cy2026, RULES
|
||||
|
||||
cf = cy2026.conversion_factor # $89.723
|
||||
skin_rate = cy2026.skin_sub_flat_rate # $127.28
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RuleYear:
|
||||
"""Annual OPPS rule parameters."""
|
||||
class RuleYear(BaseModel):
|
||||
"""Annual OPPS rule parameters for a single calendar year."""
|
||||
|
||||
year: int
|
||||
"""Calendar year."""
|
||||
|
||||
conversion_factor: float
|
||||
labor_share: float
|
||||
packaging_threshold: float
|
||||
skin_sub_payment: str # 'pass_through', 'packaged', 'flat_rate'
|
||||
skin_sub_rate: float | None # flat rate $/cm² if applicable
|
||||
"""OPPS conversion factor ($ per relative weight unit).
|
||||
Applied to APC relative weights to compute payment."""
|
||||
|
||||
labor_share: float = 0.60
|
||||
"""Labor-related share for wage index adjustment.
|
||||
Payment = CF × weight × (labor_share × WI + (1 - labor_share))."""
|
||||
|
||||
outlier_threshold: float | None = None
|
||||
"""Fixed-dollar outlier threshold. Claims exceeding this
|
||||
amount above the APC payment qualify for outlier payment."""
|
||||
|
||||
pass_through_drugs_pct: float = 1.06
|
||||
"""Payment factor for pass-through drugs/biologicals.
|
||||
ASP × this factor = payment (1.06 = ASP + 6%)."""
|
||||
|
||||
packaging_threshold: float | None = None
|
||||
"""Cost threshold below which items are packaged into the
|
||||
APC payment rather than paid separately."""
|
||||
|
||||
# Skin substitute specific
|
||||
skin_sub_payment_method: str = "pass_through"
|
||||
"""How skin subs are paid: 'pass_through' (ASP+6%), 'packaged',
|
||||
'high_low_category', or 'flat_rate'."""
|
||||
|
||||
skin_sub_flat_rate: float | None = None
|
||||
"""Flat rate $/cm² for skin subs (CY2026+, $127.28)."""
|
||||
|
||||
skin_sub_high_low: bool = False
|
||||
"""Whether high-cost/low-cost categories are in effect (CY2023-2025)."""
|
||||
|
||||
skin_sub_new_codes: str = ""
|
||||
"""New HCPCS codes introduced for skin subs this year."""
|
||||
|
||||
federal_register_citation: str = ""
|
||||
"""Federal Register citation (e.g. '90 FR 101174')."""
|
||||
|
||||
cms_rule_id: str = ""
|
||||
"""CMS rule identifier (e.g. 'CMS-1834-FC')."""
|
||||
|
||||
notes: str = ""
|
||||
"""Year-specific notes on significant policy changes."""
|
||||
|
||||
|
||||
# CY2026 — skin sub reclassification year
|
||||
cy2026 = RuleYear(
|
||||
year=2026,
|
||||
conversion_factor=89.723,
|
||||
labor_share=0.60,
|
||||
packaging_threshold=0.0,
|
||||
skin_sub_payment="flat_rate",
|
||||
skin_sub_rate=127.28,
|
||||
notes="Skin subs reclassified from drugs/biologicals to incident-to supplies",
|
||||
)
|
||||
# ── Annual rule parameters ───────────────────────────────────────
|
||||
#
|
||||
# Sources: CMS OPPS/ASC Final Rules, Federal Register
|
||||
# Conversion factors from Addendum A header / rule preamble
|
||||
|
||||
# CY2025 — last year of ASP+6% for skin subs
|
||||
cy2025 = RuleYear(
|
||||
year=2025,
|
||||
conversion_factor=87.436,
|
||||
labor_share=0.60,
|
||||
packaging_threshold=0.0,
|
||||
skin_sub_payment="pass_through",
|
||||
skin_sub_rate=None,
|
||||
notes="High-cost/low-cost skin sub categories under OPPS",
|
||||
)
|
||||
|
||||
# CY2024
|
||||
cy2024 = RuleYear(
|
||||
year=2024,
|
||||
conversion_factor=86.304,
|
||||
labor_share=0.60,
|
||||
packaging_threshold=0.0,
|
||||
skin_sub_payment="pass_through",
|
||||
skin_sub_rate=None,
|
||||
notes="High-cost/low-cost skin sub categories under OPPS",
|
||||
)
|
||||
|
||||
# CY2023 — first codification of high/low cost categories
|
||||
cy2023 = RuleYear(
|
||||
year=2023,
|
||||
conversion_factor=85.093,
|
||||
labor_share=0.60,
|
||||
packaging_threshold=0.0,
|
||||
skin_sub_payment="pass_through",
|
||||
skin_sub_rate=None,
|
||||
notes="First formal high-cost/low-cost skin sub categories (CMS-1772-FC)",
|
||||
)
|
||||
|
||||
# CY2014 — first major skin sub restructuring under OPPS
|
||||
cy2014 = RuleYear(
|
||||
year=2014,
|
||||
conversion_factor=74.305,
|
||||
labor_share=0.60,
|
||||
packaging_threshold=0.0,
|
||||
skin_sub_payment="pass_through",
|
||||
skin_sub_rate=None,
|
||||
notes="First restructuring from individual pass-through to grouped payment (CMS-1601-FC)",
|
||||
)
|
||||
|
||||
RULE_YEARS: dict[int, RuleYear] = {
|
||||
r.year: r for r in [cy2014, cy2023, cy2024, cy2025, cy2026]
|
||||
RULES: dict[int, RuleYear] = {
|
||||
2014: RuleYear(
|
||||
year=2014,
|
||||
conversion_factor=74.305,
|
||||
outlier_threshold=2885.0,
|
||||
cms_rule_id="CMS-1601-FC",
|
||||
federal_register_citation="78 FR 75196",
|
||||
skin_sub_payment_method="pass_through",
|
||||
notes="First major skin sub payment restructuring under OPPS. "
|
||||
"Moved from individual product pass-through to grouped categories.",
|
||||
),
|
||||
2015: RuleYear(
|
||||
year=2015,
|
||||
conversion_factor=75.064,
|
||||
outlier_threshold=3075.0,
|
||||
cms_rule_id="CMS-1613-FC",
|
||||
federal_register_citation="79 FR 66770",
|
||||
),
|
||||
2016: RuleYear(
|
||||
year=2016,
|
||||
conversion_factor=75.001,
|
||||
outlier_threshold=3250.0,
|
||||
cms_rule_id="CMS-1633-FC",
|
||||
federal_register_citation="80 FR 70298",
|
||||
),
|
||||
2017: RuleYear(
|
||||
year=2017,
|
||||
conversion_factor=75.001,
|
||||
outlier_threshold=3575.0,
|
||||
cms_rule_id="CMS-1656-FC",
|
||||
federal_register_citation="81 FR 79562",
|
||||
),
|
||||
2018: RuleYear(
|
||||
year=2018,
|
||||
conversion_factor=78.636,
|
||||
outlier_threshold=4325.0,
|
||||
cms_rule_id="CMS-1678-FC",
|
||||
federal_register_citation="82 FR 52356",
|
||||
),
|
||||
2019: RuleYear(
|
||||
year=2019,
|
||||
conversion_factor=80.784,
|
||||
outlier_threshold=4550.0,
|
||||
cms_rule_id="CMS-1695-FC",
|
||||
federal_register_citation="83 FR 58818",
|
||||
),
|
||||
2020: RuleYear(
|
||||
year=2020,
|
||||
conversion_factor=82.840,
|
||||
outlier_threshold=4625.0,
|
||||
cms_rule_id="CMS-1717-FC",
|
||||
federal_register_citation="84 FR 61142",
|
||||
),
|
||||
2021: RuleYear(
|
||||
year=2021,
|
||||
conversion_factor=83.324,
|
||||
outlier_threshold=5025.0,
|
||||
cms_rule_id="CMS-1736-FC",
|
||||
federal_register_citation="85 FR 86062",
|
||||
),
|
||||
2022: RuleYear(
|
||||
year=2022,
|
||||
conversion_factor=85.093,
|
||||
outlier_threshold=5350.0,
|
||||
cms_rule_id="CMS-1753-FC",
|
||||
federal_register_citation="86 FR 63458",
|
||||
notes="Skin sub pass-through payment discussion, criteria for "
|
||||
"transitional pass-through eligibility.",
|
||||
),
|
||||
2023: RuleYear(
|
||||
year=2023,
|
||||
conversion_factor=86.304,
|
||||
outlier_threshold=6175.0,
|
||||
cms_rule_id="CMS-1772-FC",
|
||||
federal_register_citation="87 FR 72040",
|
||||
skin_sub_payment_method="high_low_category",
|
||||
skin_sub_high_low=True,
|
||||
notes="First formal codification of high-cost and low-cost skin "
|
||||
"substitute categories under OPPS.",
|
||||
),
|
||||
2024: RuleYear(
|
||||
year=2024,
|
||||
conversion_factor=87.436,
|
||||
outlier_threshold=6600.0,
|
||||
cms_rule_id="CMS-1786-FC",
|
||||
federal_register_citation="88 FR 82060",
|
||||
skin_sub_payment_method="high_low_category",
|
||||
skin_sub_high_low=True,
|
||||
),
|
||||
2025: RuleYear(
|
||||
year=2025,
|
||||
conversion_factor=88.547,
|
||||
outlier_threshold=7100.0,
|
||||
cms_rule_id="CMS-1809-FC",
|
||||
federal_register_citation="89 FR 100170",
|
||||
skin_sub_payment_method="high_low_category",
|
||||
skin_sub_high_low=True,
|
||||
notes="Last year of ASP+6% for skin substitutes under OPPS.",
|
||||
),
|
||||
2026: RuleYear(
|
||||
year=2026,
|
||||
conversion_factor=89.723,
|
||||
outlier_threshold=7500.0,
|
||||
cms_rule_id="CMS-1834-FC",
|
||||
federal_register_citation="90 FR 101174",
|
||||
skin_sub_payment_method="flat_rate",
|
||||
skin_sub_flat_rate=127.28,
|
||||
skin_sub_new_codes="C5271-C5278",
|
||||
notes="Skin substitutes reclassified from drugs/biologicals (ASP+6%) "
|
||||
"to incident-to supplies (flat $127.28/cm²). New HCPCS C5271-C5278 "
|
||||
"replace Q4xxx. Estimated $9.4B savings over 10 years.",
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
# ── Convenience aliases ──────────────────────────────────────────
|
||||
|
||||
cy2014 = RULES[2014]
|
||||
cy2023 = RULES[2023]
|
||||
cy2024 = RULES[2024]
|
||||
cy2025 = RULES[2025]
|
||||
cy2026 = RULES[2026]
|
||||
|
||||
Reference in New Issue
Block a user