|
|
|
@@ -0,0 +1,207 @@
|
|
|
|
|
"""CARC / RARC code lookup tables for 835 CAS segments.
|
|
|
|
|
|
|
|
|
|
The 835 ERA (Health Care Claim Payment/Advice) transaction carries claim
|
|
|
|
|
adjustment information in ``CAS`` segments. Each ``CAS`` row has:
|
|
|
|
|
|
|
|
|
|
- a **group code** (CAS01): ``CO`` Contractual Obligation, ``PR``
|
|
|
|
|
Patient Responsibility, ``OA`` Other Adjustments, ``PI`` Payer
|
|
|
|
|
Initiated Reductions, ``CR`` Correction and Reversals.
|
|
|
|
|
- a **reason code** (CAS02): the **CARC** (Claim Adjustment Reason Code)
|
|
|
|
|
maintained by the X12 / WPC (Washington Publishing Company) committee.
|
|
|
|
|
- an amount and optional quantity.
|
|
|
|
|
|
|
|
|
|
This module is the in-memory lookup that turns those opaque codes into
|
|
|
|
|
human-readable labels for the UI. It is **not** the canonical source of
|
|
|
|
|
truth — the official list lives at
|
|
|
|
|
https://x12.org/codes/claim-adjustment-reason-codes and is updated
|
|
|
|
|
quarterly. ``LAST_UPDATED`` below is the snapshot date for the dict
|
|
|
|
|
shipped with this build.
|
|
|
|
|
|
|
|
|
|
Public API (mirrors :func:`cyclone.parsers.models_835.claim_status_label`):
|
|
|
|
|
|
|
|
|
|
- ``LAST_UPDATED`` — ISO date string (YYYY-MM-DD) of the dict snapshot.
|
|
|
|
|
- :func:`reason_label` — given ``(group, reason)`` returns the human
|
|
|
|
|
label, or ``f"Unknown ({group}-{reason})"`` if not in the dict.
|
|
|
|
|
- :func:`all_known_codes` — sorted ``[(group, reason, label), ...]``
|
|
|
|
|
for UIs that want to render the full table (e.g. an "all CARC codes"
|
|
|
|
|
reference page).
|
|
|
|
|
|
|
|
|
|
The dict is keyed ``(group, reason)`` because the same numeric reason
|
|
|
|
|
(e.g. ``97``) can appear under multiple groups (``CO-97`` "payment
|
|
|
|
|
is included in another service/procedure", ``OA-97`` "benefit
|
|
|
|
|
included in payment for another service") with different meanings.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from typing import Final
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Snapshot date for the bundled dict. Bump this when shipping a refresh.
|
|
|
|
|
LAST_UPDATED: Final[str] = "2026-06-20"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
# CARC labels — keyed (group, reason).
|
|
|
|
|
#
|
|
|
|
|
# Sources cross-referenced:
|
|
|
|
|
# - X12 / WPC "Claim Adjustment Reason Codes" master list
|
|
|
|
|
# - CMS / Noridian "Medicare CARC/RARC" reference pages (most-used codes)
|
|
|
|
|
# - Colorado Medicaid 835 companion guide (CAS codes we see in practice)
|
|
|
|
|
#
|
|
|
|
|
# Wording is paraphrased for compactness; the spec requires labels be
|
|
|
|
|
# "non-empty human-readable" — exact WPC wording is not asserted. Tests
|
|
|
|
|
# pin the *contract* (non-empty, distinct per code) rather than the text.
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_CARC_LABELS: Final[dict[tuple[str, str], str]] = {
|
|
|
|
|
# -- Contractual Obligation (CO) -------------------------------------
|
|
|
|
|
("CO", "16"): "Claim/service lacks information for adjudication",
|
|
|
|
|
("CO", "18"): "Exact duplicate claim/service",
|
|
|
|
|
("CO", "22"): "This care may be covered by another payer",
|
|
|
|
|
("CO", "29"): "The time limit for filing has expired",
|
|
|
|
|
("CO", "45"): "Charge exceeds fee schedule/maximum allowable",
|
|
|
|
|
("CO", "50"): "Non-covered services — not deemed medical necessity",
|
|
|
|
|
("CO", "96"): "Non-covered charge(s)",
|
|
|
|
|
("CO", "97"): "Payment is included in another service/procedure",
|
|
|
|
|
("CO", "109"): "Claim not covered by this payer/contractor",
|
|
|
|
|
("CO", "119"): "Benefit maximum for this period has been reached",
|
|
|
|
|
("CO", "150"): "Payer deems the information submitted does not support this level of service",
|
|
|
|
|
("CO", "151"): "Payer deems the information submitted does not support this many services",
|
|
|
|
|
("CO", "167"): "Diagnosis not covered",
|
|
|
|
|
("CO", "197"): "Precertification/authorization absent",
|
|
|
|
|
("CO", "204"): "Service/equipment not covered under patient's plan",
|
|
|
|
|
("CO", "251"): "Credentialing / provider enrollment issue",
|
|
|
|
|
("CO", "252"): "Service not on formulary",
|
|
|
|
|
("CO", "253"): "Decision based on DRG / bundled payment methodology",
|
|
|
|
|
("CO", "254"): "Claim received from ordering/referring provider not enrolled",
|
|
|
|
|
("CO", "255"): "Claim received from servicing provider not enrolled",
|
|
|
|
|
("CO", "256"): "Service not payable under provider's contract",
|
|
|
|
|
("CO", "B7"): "Provider not certified / not eligible to be paid for this service",
|
|
|
|
|
("CO", "B8"): "Alternative services were available",
|
|
|
|
|
("CO", "B9"): "Patient enrolled in another plan that covers this service",
|
|
|
|
|
("CO", "B10"): "Allowed amount has been reduced by a competitive bid",
|
|
|
|
|
("CO", "B11"): "Claim/service not covered by this payer",
|
|
|
|
|
("CO", "B12"): "Service not covered under dental benefits",
|
|
|
|
|
("CO", "B13"): "Service not covered under vision benefits",
|
|
|
|
|
("CO", "B14"): "Service not covered under pharmacy benefit",
|
|
|
|
|
("CO", "B15"): "Service requires prior authorization",
|
|
|
|
|
("CO", "B16"): "New patient qualification not met",
|
|
|
|
|
("CO", "B20"): "Procedure/service paid under a global fee",
|
|
|
|
|
("CO", "B22"): "This care is covered by another payer per coordination of benefits",
|
|
|
|
|
("CO", "B23"): "Non-covered procedure/service — not billable to patient",
|
|
|
|
|
("CO", "W1"): "Workers' compensation claim adjudicated as non-compensable",
|
|
|
|
|
("CO", "W2"): "Workers' compensation claim — jurisdictional dispute",
|
|
|
|
|
("CO", "W3"): "Workers' compensation — covered by federal program",
|
|
|
|
|
# -- Patient Responsibility (PR) -------------------------------------
|
|
|
|
|
("PR", "1"): "Deductible amount",
|
|
|
|
|
("PR", "2"): "Coinsurance amount",
|
|
|
|
|
("PR", "3"): "Co-payment amount",
|
|
|
|
|
("PR", "16"): "Claim/service lacks information — patient responsibility",
|
|
|
|
|
("PR", "22"): "Care may be covered by another payer — patient responsibility",
|
|
|
|
|
("PR", "29"): "Time limit for filing has expired — patient responsibility",
|
|
|
|
|
("PR", "45"): "Charge exceeds fee schedule — patient responsibility",
|
|
|
|
|
("PR", "50"): "Non-covered service — patient responsibility",
|
|
|
|
|
("PR", "96"): "Non-covered charge(s) — patient responsibility",
|
|
|
|
|
("PR", "97"): "Bundled service — patient responsibility",
|
|
|
|
|
("PR", "109"): "Not covered by this payer — patient responsibility",
|
|
|
|
|
("PR", "119"): "Benefit maximum reached — patient responsibility",
|
|
|
|
|
("PR", "150"): "Level-of-service not supported — patient responsibility",
|
|
|
|
|
("PR", "151"): "Frequency not supported — patient responsibility",
|
|
|
|
|
("PR", "204"): "Service not covered under plan — patient responsibility",
|
|
|
|
|
("PR", "B7"): "Provider not certified — patient responsibility",
|
|
|
|
|
("PR", "B11"): "Service not covered — patient responsibility",
|
|
|
|
|
("PR", "B22"): "Covered by another payer per COB — patient responsibility",
|
|
|
|
|
("PR", "B23"): "Non-covered procedure — billable to patient",
|
|
|
|
|
# -- Other Adjustments (OA) ------------------------------------------
|
|
|
|
|
("OA", "16"): "Missing/invalid information — other adjustment",
|
|
|
|
|
("OA", "18"): "Exact duplicate claim/service — other adjustment",
|
|
|
|
|
("OA", "23"): "Impact of prior payer adjudication",
|
|
|
|
|
("OA", "29"): "Time limit for filing — other adjustment",
|
|
|
|
|
("OA", "45"): "Charge exceeds fee schedule — other adjustment",
|
|
|
|
|
("OA", "50"): "Non-covered service — other adjustment",
|
|
|
|
|
("OA", "97"): "Payment included in another service — other adjustment",
|
|
|
|
|
("OA", "109"): "Not covered by this payer — other adjustment",
|
|
|
|
|
("OA", "119"): "Benefit maximum reached — other adjustment",
|
|
|
|
|
("OA", "150"): "Level of service not supported — other adjustment",
|
|
|
|
|
("OA", "151"): "Frequency not supported — other adjustment",
|
|
|
|
|
("OA", "204"): "Service not covered — other adjustment",
|
|
|
|
|
("OA", "B7"): "Provider not certified — other adjustment",
|
|
|
|
|
("OA", "B11"): "Service not covered — other adjustment",
|
|
|
|
|
("OA", "B22"): "Covered by another payer — other adjustment",
|
|
|
|
|
("OA", "B23"): "Non-covered procedure — other adjustment",
|
|
|
|
|
# -- Payer Initiated (PI) --------------------------------------------
|
|
|
|
|
("PI", "16"): "Missing information — payer-initiated reduction",
|
|
|
|
|
("PI", "21"): "Penalty for late filing",
|
|
|
|
|
("PI", "22"): "Care covered by another payer — payer-initiated reduction",
|
|
|
|
|
("PI", "25"): "Payment adjusted based on medical review",
|
|
|
|
|
("PI", "29"): "Time limit expired — payer-initiated reduction",
|
|
|
|
|
("PI", "45"): "Charge exceeds fee schedule — payer-initiated reduction",
|
|
|
|
|
("PI", "50"): "Non-covered service — payer-initiated reduction",
|
|
|
|
|
("PI", "97"): "Bundled service — payer-initiated reduction",
|
|
|
|
|
("PI", "109"): "Not covered by this payer — payer-initiated reduction",
|
|
|
|
|
("PI", "119"): "Benefit maximum — payer-initiated reduction",
|
|
|
|
|
("PI", "150"): "Level of service not supported — payer-initiated reduction",
|
|
|
|
|
("PI", "151"): "Frequency not supported — payer-initiated reduction",
|
|
|
|
|
("PI", "204"): "Service not covered under plan — payer-initiated reduction",
|
|
|
|
|
("PI", "B7"): "Provider not certified — payer-initiated reduction",
|
|
|
|
|
("PI", "B11"): "Service not covered — payer-initiated reduction",
|
|
|
|
|
("PI", "B22"): "Covered by another payer — payer-initiated reduction",
|
|
|
|
|
("PI", "B23"): "Non-covered procedure — payer-initiated reduction",
|
|
|
|
|
# -- Correction and Reversal (CR) ------------------------------------
|
|
|
|
|
("CR", "1"): "Deductible amount — correction/reversal",
|
|
|
|
|
("CR", "2"): "Coinsurance amount — correction/reversal",
|
|
|
|
|
("CR", "3"): "Co-payment amount — correction/reversal",
|
|
|
|
|
("CR", "4"): "Procedure code inconsistency — correction/reversal",
|
|
|
|
|
("CR", "16"): "Missing information — correction/reversal",
|
|
|
|
|
("CR", "29"): "Time limit expired — correction/reversal",
|
|
|
|
|
("CR", "45"): "Charge exceeds fee schedule — correction/reversal",
|
|
|
|
|
("CR", "50"): "Non-covered service — correction/reversal",
|
|
|
|
|
("CR", "97"): "Bundled service — correction/reversal",
|
|
|
|
|
("CR", "109"): "Not covered by this payer — correction/reversal",
|
|
|
|
|
("CR", "119"): "Benefit maximum — correction/reversal",
|
|
|
|
|
("CR", "150"): "Level of service not supported — correction/reversal",
|
|
|
|
|
("CR", "151"): "Frequency not supported — correction/reversal",
|
|
|
|
|
("CR", "204"): "Service not covered — correction/reversal",
|
|
|
|
|
("CR", "B7"): "Provider not certified — correction/reversal",
|
|
|
|
|
("CR", "B11"): "Service not covered — correction/reversal",
|
|
|
|
|
("CR", "B22"): "Covered by another payer — correction/reversal",
|
|
|
|
|
("CR", "B23"): "Non-covered procedure — correction/reversal",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
# Public API
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def reason_label(group_code: str, reason_code: str) -> str:
|
|
|
|
|
"""Return the human-readable label for a ``(group, reason)`` pair.
|
|
|
|
|
|
|
|
|
|
Falls back to ``f"Unknown ({group_code}-{reason_code})"`` when the
|
|
|
|
|
code is not in the bundled dict. The fallback is a stable, parseable
|
|
|
|
|
string so callers can distinguish "we don't know" from "known empty"
|
|
|
|
|
(there are no known-empty labels in the dict).
|
|
|
|
|
"""
|
|
|
|
|
return _CARC_LABELS.get(
|
|
|
|
|
(group_code, reason_code),
|
|
|
|
|
f"Unknown ({group_code}-{reason_code})",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def all_known_codes() -> list[tuple[str, str, str]]:
|
|
|
|
|
"""Return every known code as a sorted ``[(group, reason, label), ...]``.
|
|
|
|
|
|
|
|
|
|
The result is sorted lexicographically by ``(group, reason)`` so UIs
|
|
|
|
|
can render the full table without further work. Pairs are unique by
|
|
|
|
|
construction (the dict cannot have duplicate keys).
|
|
|
|
|
"""
|
|
|
|
|
return sorted((g, r, lbl) for (g, r), lbl in _CARC_LABELS.items())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
"LAST_UPDATED",
|
|
|
|
|
"reason_label",
|
|
|
|
|
"all_known_codes",
|
|
|
|
|
]
|