Some checks failed
CI / lint (push) Successful in 31s
CI / test (push) Failing after 2m16s
Infra CI / notebooks (push) Successful in 53s
Infra CI / docs (push) Successful in 1m30s
Infra CI / api (push) Successful in 1m0s
Infra CI / mc (push) Failing after 32s
Infra CI / llm (push) Successful in 47s
CI / notebooks-smoke (push) Successful in 1m40s
Infra CI / zotero (push) Successful in 16s
CI / lint (pull_request) Successful in 47s
Infra CI / zotero (pull_request) Successful in 14s
Infra CI / docs (pull_request) Successful in 19s
Infra CI / notebooks (pull_request) Successful in 56s
Infra CI / api (pull_request) Successful in 16s
CI / notebooks-smoke (pull_request) Successful in 1m33s
CI / test (pull_request) Failing after 2m35s
Infra CI / mc (pull_request) Failing after 32s
Infra CI / llm (pull_request) Successful in 14s
The connector (bcda.express.cclf / bcda.pipe.cclf) still routed on the v2 near-line RIC code, read v2-only amount columns, and had never run end to end: its contracts named CCLF columns the EOB table does not have, so the runner's exact-match check would have refused every stage. One header stage now carries the v3 semantics. _stg_claim_header drops NotFinalAction claims (9% of the sandbox), derives claim_family from EOB-TYPE → CLM-TYPE-CD → pde_id → RIC (v3 emits the RIC on only some claims), collapses a claim seen in two sources on its claim control number (NationalClaimsHistory/DDPS over SharedSystem, then newest last_updated; rows without a control number are never collapsed) and resolves the MBI. The four family stages are filters on it. One mapping produces input_layer.medical_claim for institutional, carrier and DME lines: admission/discharge from the C4BB admission period, NUBC type of bill (new clm_bill_type_cd on the EOB table; rebuilt as "0" + the three-character v3 frequency code when the coding is missing — the v2 fac+clsfctn+freq concatenation yields "88787J" on v3), MS-DRG, revenue centre, HCPCS + modifiers, attending→operating→rendering / rendering / rendering→ordering NPIs, billing Organization NPI and tax number, paid/allowed/charge/coinsurance/deductible from the consolidated v3 Adjudication amounts, paid date from clm_pd_dt → NCH weekly → CMS process. Part D uses the PDE id, prescribing care-team NPI, contained pharmacy NPI, NDC quantity, total drug cost as charge and paid-by-patient as copayment. Eligibility reads the Part A row (Part B fallback) for status, entitlement and enrollment, the Dual row for dual status, and accepts both CCW sex codes and the FHIR words the v2 flattener passed through. Contracts inherit: header stages subclass ExplanationOfBenefit, outputs subclass aco.table.input_layer.InputLayer*, so downstream pipelines run on BCDA output exactly as on CCLF output. load_bcda(run_pipeline=True), stack load bcda --run-pipeline and stack run bcda land input_layer.*. Large-entity sandbox pull: 221,021 medical lines on 28,282 claims (equal to the FinalAction non-PDE EOBs by type), 11,968 pharmacy rows, 9,582 eligibility rows; all 16 reconciliation checks in the notebook pass. Tests run the whole connector on CMS's official v3 samples through DuckDB. refs #1139
1323 lines
49 KiB
Python
1323 lines
49 KiB
Python
"""bcda.express.v3 — BCDA v3 (C4BB 2.2.0) flatteners.
|
|
|
|
Two layers: unit tests on hand-built resources that exercise every
|
|
branch of the extraction primitives, and invariants over CMS's
|
|
official v3 sample files vendored under ``dev/vendor/bcda-site``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from datetime import date
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from bcda.express import v3
|
|
from bcda.express.flatten import flatten_coverage, flatten_eob, flatten_patient
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
SAMPLES = ROOT / "dev" / "vendor" / "bcda-site"
|
|
|
|
SD, CS = v3.SD, v3.CS
|
|
|
|
|
|
def _ndjson(name: str) -> list[dict]:
|
|
path = SAMPLES / name
|
|
with path.open() as f:
|
|
return [json.loads(line) for line in f if line.strip()]
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def sample_patients() -> list[dict]:
|
|
return _ndjson("v3_Patient.ndjson")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def sample_coverages() -> list[dict]:
|
|
return _ndjson("v3_Coverage.ndjson")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def sample_eobs() -> list[dict]:
|
|
return _ndjson("v3_ExplanationOfBenefit.ndjson")
|
|
|
|
|
|
# ── primitives ───────────────────────────────────────────────
|
|
|
|
|
|
class TestPrimitives:
|
|
def test_get_and_scalars(self) -> None:
|
|
assert v3._get({"a": {"b": 1}}, "a", "b") == 1
|
|
assert v3._get({"a": 1}, "a", "b") is None
|
|
assert v3._get(None, "a") is None
|
|
assert v3._date("2024-01-02T00:00:00Z") == date(2024, 1, 2)
|
|
assert v3._date("not a date") is None
|
|
assert v3._date(None) is None
|
|
assert v3._date(42) is None
|
|
assert v3._num("1.5") == 1.5
|
|
assert v3._num(True) is None
|
|
assert v3._num("x") is None
|
|
assert v3._num(None) is None
|
|
assert v3._ref_id("Patient/-1") == "-1"
|
|
assert v3._ref_id("#org") == "org"
|
|
assert v3._ref_id("") is None
|
|
assert v3._ref_id(None) is None
|
|
|
|
def test_coding_and_has_coding(self) -> None:
|
|
cc = {
|
|
"coding": [
|
|
{"system": "http://x/A", "code": "a"},
|
|
{"system": "http://y/B", "code": "b"},
|
|
]
|
|
}
|
|
assert v3._coding(cc) == "a"
|
|
assert v3._coding(cc, "http://y/B") == "b"
|
|
assert v3._coding(cc, "/B") == "b" # suffix match
|
|
assert v3._coding(cc, "nope") is None
|
|
assert v3._coding(None) is None
|
|
assert v3._coding("string") is None
|
|
assert v3._has_coding(cc, "http://x/A", "a")
|
|
assert not v3._has_coding(cc, "http://x/A", "b")
|
|
assert not v3._has_coding(None, "s", "c")
|
|
|
|
@pytest.mark.parametrize(
|
|
"ext, expected",
|
|
[
|
|
({"valueCoding": {"code": "Z"}}, "Z"),
|
|
({"valueCode": "c"}, "c"),
|
|
({"valueString": "s"}, "s"),
|
|
({"valueDate": "2020-01-01"}, "2020-01-01"),
|
|
({"valueDateTime": "2020-01-01T00:00:00Z"}, "2020-01-01T00:00:00Z"),
|
|
({"valueBoolean": True}, True),
|
|
({"valueDecimal": 1.5}, 1.5),
|
|
({"valueInteger": 3}, 3),
|
|
({"valueUnsignedInt": 4}, 4),
|
|
({"valuePositiveInt": 5}, 5),
|
|
({"valueQuantity": {"value": 7}}, 7),
|
|
({"valueMoney": {"value": 9.5}}, 9.5),
|
|
({"valueIdentifier": {"value": "id"}}, "id"),
|
|
({"valueReference": {"reference": "x"}}, None),
|
|
],
|
|
)
|
|
def test_ext_value(self, ext: dict, expected: object) -> None:
|
|
assert v3._ext_value(ext) == expected
|
|
|
|
def test_ext_lookup(self) -> None:
|
|
exts = [
|
|
{"url": SD + "X", "valueCoding": {"code": "1"}},
|
|
{"url": "other", "valueString": "n"},
|
|
]
|
|
assert v3._ext(exts, "X") == "1"
|
|
assert v3._ext(exts, "Y") is None
|
|
assert v3._ext(None, "X") is None
|
|
assert v3._ext_str(exts, "X") == "1"
|
|
assert v3._ext_str(exts, "Y") is None
|
|
|
|
def test_identifiers(self) -> None:
|
|
ids = [
|
|
{"system": "http://a/one", "value": "1"},
|
|
{"type": {"coding": [{"system": "sys", "code": "uc"}]}, "value": "UC"},
|
|
]
|
|
assert v3._identifier(ids, "http://a/one") == "1"
|
|
assert v3._identifier(ids, "one") == "1"
|
|
assert v3._identifier(ids, "zzz") is None
|
|
assert v3._identifier(None, "x") is None
|
|
assert v3._identifier_typed(ids, "sys", "uc") == "UC"
|
|
assert v3._identifier_typed(ids, "sys", "xx") is None
|
|
assert v3._identifier_typed(None, "sys", "uc") is None
|
|
|
|
def test_tag(self) -> None:
|
|
r = {"meta": {"tag": [{"system": "s", "code": "c"}]}}
|
|
assert v3._tag(r, "s") == "c"
|
|
assert v3._tag(r, "t") is None
|
|
assert v3._tag({}, "s") is None
|
|
|
|
def test_supporting_info(self) -> None:
|
|
infos = [
|
|
{
|
|
"category": {
|
|
"coding": [{"system": CS + "Supporting-Information", "code": "A"}]
|
|
},
|
|
"code": {
|
|
"coding": [
|
|
{"system": CS + "X", "code": "ax"},
|
|
{"system": "o", "code": "ao"},
|
|
]
|
|
},
|
|
"timingPeriod": {"start": "2020-01-01", "end": "2020-02-01"},
|
|
"valueString": "vs",
|
|
},
|
|
{
|
|
"category": {
|
|
"coding": [{"system": CS + "Supporting-Information", "code": "B"}]
|
|
},
|
|
"timingDate": "2021-03-04",
|
|
"valueQuantity": {"value": 3},
|
|
},
|
|
{
|
|
"category": {
|
|
"coding": [{"system": CS + "Supporting-Information", "code": "C"}]
|
|
},
|
|
"valueBoolean": True,
|
|
},
|
|
{
|
|
"category": {
|
|
"coding": [{"system": CS + "Supporting-Information", "code": "D"}]
|
|
},
|
|
},
|
|
]
|
|
assert v3._si(infos, "A")["valueString"] == "vs"
|
|
assert v3._si(infos, "nope") is None
|
|
assert v3._si(None, "A") is None
|
|
assert len(v3._si_all(infos, "A")) == 1
|
|
assert v3._si_code(infos, "A") == "ax"
|
|
assert v3._si_code(infos, "A", code_system="o") == "ao"
|
|
assert v3._si_code(infos, "B") is None
|
|
assert v3._si_code(infos, "Q") is None
|
|
assert v3._si_code_by_system(infos, CS + "X") == "ax"
|
|
assert v3._si_code_by_system(infos, CS + "Nope") is None
|
|
assert v3._si_date(infos, "A") == date(2020, 1, 1)
|
|
assert v3._si_date(infos, "B") == date(2021, 3, 4)
|
|
assert v3._si_date(infos, "Q") is None
|
|
assert v3._si_period(infos, "A") == (date(2020, 1, 1), date(2020, 2, 1))
|
|
assert v3._si_period(infos, "B") == (date(2021, 3, 4), None)
|
|
assert v3._si_period(infos, "Q") == (None, None)
|
|
assert v3._si_value(infos, "A") == "vs"
|
|
assert v3._si_value(infos, "B") == 3
|
|
assert v3._si_value(infos, "C") is True
|
|
assert v3._si_value(infos, "D") is None
|
|
assert v3._si_value(infos, "Q") is None
|
|
|
|
def test_adjudication(self) -> None:
|
|
adjs = [
|
|
{
|
|
"category": {
|
|
"coding": [{"system": CS + "Adjudication", "code": "AMT"}]
|
|
},
|
|
"amount": {"value": 1.5},
|
|
},
|
|
{
|
|
"category": {
|
|
"coding": [{"system": CS + "Adjudication", "code": "CNT"}]
|
|
},
|
|
"value": 3,
|
|
},
|
|
{
|
|
"category": {
|
|
"coding": [{"system": CS + "Adjudication", "code": "QTY"}]
|
|
},
|
|
"quantity": {"value": 4},
|
|
},
|
|
]
|
|
assert v3._adj_amount(adjs, "AMT") == 1.5
|
|
assert v3._adj_amount(adjs, "CNT") is None
|
|
assert v3._adj_amount(adjs, "NOPE") is None
|
|
assert v3._adj_value(adjs, "CNT") == 3
|
|
assert v3._adj_value(adjs, "NOPE") is None
|
|
assert v3._adj_quantity(adjs, "CNT") == 3
|
|
assert v3._adj_quantity(adjs, "QTY") == 4
|
|
assert v3._adj_quantity(adjs, "NOPE") is None
|
|
assert v3._adj_by_code(None, "AMT") is None
|
|
|
|
def test_contained_and_names(self) -> None:
|
|
r = {"contained": [{"id": "org", "name": "ORG"}]}
|
|
assert v3._contained(r, "#org")["name"] == "ORG"
|
|
assert v3._contained(r, "#missing") is None
|
|
assert v3._contained(r, None) is None
|
|
assert v3._display_name(None) is None
|
|
assert v3._display_name("Acme") == "Acme"
|
|
assert (
|
|
v3._display_name([{"family": "Doe", "given": ["Jane", "Q"]}])
|
|
== "Doe, Jane Q"
|
|
)
|
|
assert v3._display_name([{"text": "Dr Who"}]) == "Dr Who"
|
|
assert v3._display_name([{}]) is None
|
|
assert v3._display_name(["x"]) is None
|
|
assert v3._display_name([]) is None
|
|
assert v3._display_name(42) == "42"
|
|
|
|
def test_care_team_and_npi(self) -> None:
|
|
members = [
|
|
{
|
|
"role": {"coding": [{"code": "rendering"}, {"code": "rendering"}]},
|
|
"provider": {"identifier": {"system": v3.US_NPI, "value": "111"}},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "attending"}]},
|
|
"provider": {
|
|
"identifier": {
|
|
"type": {
|
|
"coding": [
|
|
{
|
|
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
|
|
"code": "NPI",
|
|
}
|
|
]
|
|
},
|
|
"value": "222",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "referring"}]},
|
|
"provider": {"identifier": {"system": "upin", "value": "U"}},
|
|
},
|
|
{"role": {}, "provider": {}},
|
|
]
|
|
ct = v3._care_team(members)
|
|
assert set(ct) == {"rendering", "attending", "referring"}
|
|
assert v3._npi(ct["rendering"][0]) == "111"
|
|
assert v3._npi(ct["attending"][0]) == "222"
|
|
assert v3._npi(ct["referring"][0]) is None
|
|
assert v3._npi(None) is None
|
|
assert v3._npi({"provider": {"identifier": "oops"}}) is None
|
|
assert v3._provider_value(ct["referring"][0]) == "U"
|
|
assert v3._care_team(None) == {}
|
|
|
|
|
|
class TestIsV3:
|
|
def test_profile(self) -> None:
|
|
assert v3.is_v3(
|
|
{
|
|
"meta": {
|
|
"profile": [
|
|
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient|2.2.0"
|
|
]
|
|
}
|
|
}
|
|
)
|
|
assert not v3.is_v3(
|
|
{
|
|
"meta": {
|
|
"profile": [
|
|
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient|1.0.0"
|
|
]
|
|
}
|
|
}
|
|
)
|
|
assert not v3.is_v3({"meta": {"profile": [None]}})
|
|
|
|
def test_tag_extension_identifier(self) -> None:
|
|
assert v3.is_v3(
|
|
{"meta": {"tag": [{"system": v3.CS_SYSTEM_TYPE, "code": "DDPS"}]}}
|
|
)
|
|
assert v3.is_v3({"extension": [{"url": SD + "X"}]})
|
|
assert v3.is_v3({"identifier": [{"system": v3.ID_CLM_CNTL}]})
|
|
assert not v3.is_v3(
|
|
{
|
|
"extension": [
|
|
{"url": "https://bluebutton.cms.gov/resources/variables/race"}
|
|
]
|
|
}
|
|
)
|
|
assert not v3.is_v3({})
|
|
|
|
|
|
# ── Patient ──────────────────────────────────────────────────
|
|
|
|
|
|
def _patient(**over: object) -> dict:
|
|
base = {
|
|
"resourceType": "Patient",
|
|
"id": "-7",
|
|
"meta": {
|
|
"lastUpdated": "2026-01-01T00:00:00Z",
|
|
"profile": [
|
|
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient|2.2.0"
|
|
],
|
|
},
|
|
"identifier": [
|
|
{
|
|
"system": v3.US_MBI,
|
|
"value": "OLD1",
|
|
"period": {"start": "2010-01-01", "end": "2015-01-01"},
|
|
},
|
|
{"system": v3.US_MBI, "value": "CUR", "period": {"start": "2020-01-01"}},
|
|
{
|
|
"system": v3.US_MBI,
|
|
"value": "OLD2",
|
|
"period": {"start": "2015-01-01", "end": "2020-01-01"},
|
|
},
|
|
{"system": "other", "value": "x"},
|
|
],
|
|
"name": [{"family": "Doe", "given": ["Jane", "Q"]}],
|
|
"birthDate": "1950-02-03",
|
|
"deceasedDateTime": "2025-01-01T00:00:00Z",
|
|
"gender": "female",
|
|
"address": [
|
|
{
|
|
"line": ["1 A St", "Apt 2", "L3", "L4", "L5", "L6"],
|
|
"city": "Town",
|
|
"state": "TX",
|
|
"postalCode": "775501234",
|
|
}
|
|
],
|
|
"extension": [
|
|
{"url": v3.US_CORE_SEX, "valueCode": "248152002"},
|
|
{
|
|
"url": v3.US_CORE_RACE,
|
|
"extension": [
|
|
{"url": "ombCategory", "valueCoding": {"code": "2054-5"}},
|
|
{"url": "text", "valueString": "Black"},
|
|
],
|
|
},
|
|
{
|
|
"url": v3.US_CORE_ETHNICITY,
|
|
"extension": [
|
|
{"url": "ombCategory", "valueCoding": {"code": "2186-5"}}
|
|
],
|
|
},
|
|
],
|
|
"communication": [
|
|
{"language": {"coding": [{"system": "urn:ietf:bcp:47", "code": "es"}]}}
|
|
],
|
|
"link": [
|
|
{
|
|
"type": "replaced-by",
|
|
"other": {"reference": "Patient/-9", "display": "-9"},
|
|
},
|
|
{"type": "seealso", "other": {"display": "-8"}},
|
|
],
|
|
}
|
|
base.update(over)
|
|
return base
|
|
|
|
|
|
class TestFlattenPatientV3:
|
|
def test_dispatch_and_identity(self) -> None:
|
|
p = flatten_patient(_patient())
|
|
assert p.id == "-7"
|
|
assert p.bene_id == "-7" # BENE_SK
|
|
assert p.bene_mbi_id == "CUR"
|
|
assert p.identifier_currency == "current"
|
|
assert p.crnt_num == "CUR"
|
|
assert p.mbi_efctv_dt == date(2020, 1, 1)
|
|
assert p.prvs_num == "OLD2" # most recent historic
|
|
assert p.efctv_bgn_dt == date(2015, 1, 1)
|
|
assert p.efctv_end_dt == date(2020, 1, 1)
|
|
assert p.xref_efctv_sk == "-9"
|
|
assert p.bene_sk_list == "-9;-8;-7"
|
|
assert p.cntct_lang_cd == "es"
|
|
|
|
def test_demographics(self) -> None:
|
|
p = flatten_patient(_patient())
|
|
assert (p.bene_1st_name, p.bene_midl_name, p.bene_last_name) == (
|
|
"Jane",
|
|
"Q",
|
|
"Doe",
|
|
)
|
|
assert p.bene_dob == date(1950, 2, 3)
|
|
assert p.bene_death_dt == date(2025, 1, 1)
|
|
assert p.bene_sex_cd == "2"
|
|
assert p.us_core_sex == "248152002"
|
|
assert (p.us_core_race, p.bene_race_cd) == ("2054-5", "2")
|
|
assert p.geo_zip5_cd == "77550"
|
|
assert p.geo_zip4_cd == "1234"
|
|
assert p.bene_zip_cd == "775501234"
|
|
assert p.bene_line_6_adr == "L6"
|
|
assert p.geo_zip_plc_name == "Town"
|
|
assert p.geo_usps_state_cd == "TX"
|
|
assert p.rfrnc_yr is None and p.dual_01 is None
|
|
|
|
def test_hispanic_wins_and_unknowns(self) -> None:
|
|
r = _patient(
|
|
extension=[
|
|
{
|
|
"url": v3.US_CORE_ETHNICITY,
|
|
"extension": [
|
|
{"url": "ombCategory", "valueCoding": {"code": v3.HISPANIC_OMB}}
|
|
],
|
|
}
|
|
]
|
|
)
|
|
p = flatten_patient(r)
|
|
assert (p.us_core_race, p.bene_race_cd) == (None, "5")
|
|
r = _patient(
|
|
extension=[
|
|
{
|
|
"url": v3.US_CORE_RACE,
|
|
"extension": [
|
|
{"url": "ombCategory", "valueCoding": {"code": "9999-9"}}
|
|
],
|
|
}
|
|
]
|
|
)
|
|
assert flatten_patient(r).bene_race_cd == "3" # unmapped OMB → Other
|
|
r = _patient(
|
|
extension=[
|
|
{
|
|
"url": v3.US_CORE_RACE,
|
|
"extension": [
|
|
{"url": "ombCategory", "valueCoding": {"code": "UNK"}}
|
|
],
|
|
}
|
|
]
|
|
)
|
|
assert flatten_patient(r).bene_race_cd == "0"
|
|
assert flatten_patient(_patient(extension=[])).bene_race_cd is None
|
|
|
|
def test_sex_fallbacks(self) -> None:
|
|
assert flatten_patient(_patient(extension=[], gender="male")).bene_sex_cd == "1"
|
|
assert (
|
|
flatten_patient(_patient(extension=[], gender="other")).bene_sex_cd == "0"
|
|
)
|
|
assert flatten_patient(_patient(extension=[], gender=None)).bene_sex_cd is None
|
|
|
|
def test_mbi_edge_cases(self) -> None:
|
|
# all MBIs closed → latest end is "current" (historic flag), next is previous
|
|
ids = [
|
|
{
|
|
"system": v3.US_MBI,
|
|
"value": "A",
|
|
"period": {"start": "2010-01-01", "end": "2012-01-01"},
|
|
},
|
|
{
|
|
"system": v3.US_MBI,
|
|
"value": "B",
|
|
"period": {"start": "2012-01-01", "end": "2014-01-01"},
|
|
},
|
|
]
|
|
p = flatten_patient(_patient(identifier=ids))
|
|
assert (p.bene_mbi_id, p.identifier_currency, p.prvs_num) == (
|
|
"B",
|
|
"historic",
|
|
"A",
|
|
)
|
|
p = flatten_patient(_patient(identifier=ids[:1]))
|
|
assert (p.bene_mbi_id, p.prvs_num) == ("A", None)
|
|
p = flatten_patient(_patient(identifier=[]))
|
|
assert (
|
|
p.bene_mbi_id is None
|
|
and p.identifier_currency is None
|
|
and p.mbi_efctv_dt is None
|
|
)
|
|
p = flatten_patient(
|
|
_patient(identifier=[{"system": v3.US_MBI, "value": "ONLY"}])
|
|
)
|
|
assert (p.bene_mbi_id, p.prvs_num, p.efctv_bgn_dt) == ("ONLY", None, None)
|
|
|
|
def test_minimal(self) -> None:
|
|
p = flatten_patient(
|
|
{
|
|
"meta": {
|
|
"profile": [
|
|
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient|2.2.0"
|
|
]
|
|
}
|
|
}
|
|
)
|
|
assert p.id is None and p.xref_efctv_sk is None and p.bene_sk_list is None
|
|
assert p.geo_zip5_cd is None and p.bene_1st_name is None
|
|
|
|
def test_v2_payload_still_routes_to_v2(self) -> None:
|
|
r = {
|
|
"id": "P1",
|
|
"identifier": [{"system": "http://ccw/bene_id", "value": "B1"}],
|
|
"extension": [
|
|
{
|
|
"url": "https://bluebutton.cms.gov/resources/variables/race",
|
|
"valueCoding": {"code": "1"},
|
|
}
|
|
],
|
|
}
|
|
p = flatten_patient(r)
|
|
assert p.bene_id == "B1" and p.bene_race_cd == "1"
|
|
|
|
|
|
# ── Coverage ─────────────────────────────────────────────────
|
|
|
|
|
|
def _coverage(plan: str, **over: object) -> dict:
|
|
base = {
|
|
"resourceType": "Coverage",
|
|
"id": f"{plan}-1",
|
|
"meta": {
|
|
"lastUpdated": "2026-01-01T00:00:00Z",
|
|
"profile": [
|
|
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Coverage|2.2.0"
|
|
],
|
|
},
|
|
"status": "active",
|
|
"subscriberId": "MBI1",
|
|
"beneficiary": {"reference": "Patient/-7"},
|
|
"type": {"coding": [{"system": "https://nahdo.org/sopt", "code": "1"}]},
|
|
"class": [
|
|
{"type": {"coding": [{"code": "group"}]}, "value": "Medicare"},
|
|
{"type": {"coding": [{"code": "plan"}]}, "value": plan},
|
|
],
|
|
"period": {"start": "2024-01-01", "end": "2024-12-31"},
|
|
"extension": [
|
|
{"url": SD + "BENE-MDCR-STUS-CD", "valueCoding": {"code": "10"}},
|
|
{"url": SD + "BENE-MDCR-ENTLMT-RSN-CD", "valueCoding": {"code": "0"}},
|
|
{"url": SD + "BENE-ESRD-STUS-ID", "valueCoding": {"code": "N"}},
|
|
{"url": SD + "BENE-MDCR-ENTLMT-STUS-CD", "valueCoding": {"code": "Y"}},
|
|
{"url": SD + "BENE-BUYIN-CD", "valueCoding": {"code": "B"}},
|
|
],
|
|
}
|
|
base.update(over)
|
|
return base
|
|
|
|
|
|
class TestFlattenCoverageV3:
|
|
def test_part_a(self) -> None:
|
|
c = flatten_coverage(_coverage("Part A"))
|
|
assert c.class_plan == "Part A" and c.class_group == "Medicare"
|
|
assert c.beneficiary_reference == "-7" and c.subscriber_id == "MBI1"
|
|
assert c.coverage_type == "1"
|
|
assert (c.period_start, c.period_end) == (date(2024, 1, 1), date(2024, 12, 31))
|
|
assert (c.bene_part_a_enrlmt_bgn_dt, c.mdcr_covg_a_end_dt) == (
|
|
date(2024, 1, 1),
|
|
date(2024, 12, 31),
|
|
)
|
|
assert c.bene_part_b_enrlmt_bgn_dt is None
|
|
assert (c.ms_cd, c.orec, c.esrd_ind, c.buyin_cd) == ("10", "0", "N", "B")
|
|
assert (c.entlmt_stus_cd, c.a_trm_cd, c.b_trm_cd) == ("Y", "Y", None)
|
|
|
|
def test_part_b_and_d(self) -> None:
|
|
b = flatten_coverage(_coverage("Part B"))
|
|
assert (b.bene_part_b_enrlmt_bgn_dt, b.mdcr_covg_b_end_dt) == (
|
|
date(2024, 1, 1),
|
|
date(2024, 12, 31),
|
|
)
|
|
assert (b.a_trm_cd, b.b_trm_cd) == (None, "Y")
|
|
d = flatten_coverage(
|
|
_coverage(
|
|
"Part D",
|
|
extension=[
|
|
{"url": SD + "BENE-CNTRCT-NUM", "valueString": "S0001"},
|
|
{"url": SD + "BENE-PBP-NUM", "valueString": "001"},
|
|
{"url": SD + "CNTRCT-PBP-SGMT-NUM", "valueString": "7"},
|
|
{"url": SD + "BENE-LIS-EFCTV-CD", "valueCoding": {"code": "1"}},
|
|
{"url": SD + "BENE-LIS-COPMT-LVL-CD", "valueCoding": {"code": "2"}},
|
|
{"url": SD + "BENE-LIS-PTD-PRM-PCT", "valueDecimal": 100},
|
|
{"url": SD + "BENE-ENRLMT-EMPLR-SBSDY-SW", "valueBoolean": False},
|
|
],
|
|
contained=[
|
|
{
|
|
"resourceType": "Organization",
|
|
"id": "plan-org",
|
|
"name": "Big PDP",
|
|
},
|
|
{"resourceType": "Organization", "id": "cms-org", "name": "CMS"},
|
|
],
|
|
)
|
|
)
|
|
assert (d.mdcr_covg_d_bgn_dt, d.mdcr_covg_d_end_dt) == (
|
|
date(2024, 1, 1),
|
|
date(2024, 12, 31),
|
|
)
|
|
assert (d.cntrct_num, d.pbp_num, d.pbp_sgmt_num) == ("S0001", "001", "7")
|
|
assert (d.lis_efctv_cd, d.lis_copmt_lvl_cd, d.lis_ptd_prm_pct, d.rds_sw) == (
|
|
"1",
|
|
"2",
|
|
"100",
|
|
"False",
|
|
)
|
|
assert d.cntrct_pbp_name == "Big PDP"
|
|
|
|
def test_part_c_rx_classes_and_dual(self) -> None:
|
|
c = flatten_coverage(
|
|
_coverage(
|
|
"Part C",
|
|
**{
|
|
"class": [
|
|
{"type": {"coding": [{"code": "plan"}]}, "value": "Part C"},
|
|
{"type": {"coding": [{"code": "rxid"}]}, "value": "RID"},
|
|
{"type": {"coding": [{"code": "rxgroup"}]}, "value": "RG"},
|
|
{"type": {"coding": [{"code": "rxpcn"}]}, "value": "PCN"},
|
|
{"type": {"coding": [{"code": "rxbin"}]}, "value": "BIN"},
|
|
{"type": {"coding": [{"code": "weird"}]}, "value": "?"},
|
|
],
|
|
"extension": [
|
|
{"url": SD + "BENE-CVRG-TYPE-CD", "valueCoding": {"code": "11"}}
|
|
],
|
|
"contained": [
|
|
{"resourceType": "Organization", "id": "cms-org", "name": "CMS"}
|
|
],
|
|
},
|
|
)
|
|
)
|
|
assert (c.rx_id, c.rx_group, c.rx_pcn, c.rx_bin) == ("RID", "RG", "PCN", "BIN")
|
|
assert (
|
|
c.cvrg_type_cd == "11"
|
|
and c.cntrct_pbp_name is None
|
|
and c.class_group is None
|
|
)
|
|
assert c.bene_part_a_enrlmt_bgn_dt is None and c.mdcr_covg_d_bgn_dt is None
|
|
dual = flatten_coverage(
|
|
_coverage(
|
|
"Dual Medicare/Medicaid",
|
|
extension=[
|
|
{"url": SD + "BENE-DUAL-STUS-CD", "valueCoding": {"code": "08"}},
|
|
{"url": SD + "BENE-DUAL-TYPE-CD", "valueCoding": {"code": "N"}},
|
|
{"url": SD + "MEDICAID-STATE-CD", "valueCoding": {"code": "VA"}},
|
|
],
|
|
)
|
|
)
|
|
assert (dual.dual_stus_cd, dual.dual_type_cd, dual.medicaid_state_cd) == (
|
|
"08",
|
|
"N",
|
|
"VA",
|
|
)
|
|
|
|
def test_minimal_uses_mbi_identifier(self) -> None:
|
|
c = flatten_coverage(
|
|
{
|
|
"meta": {
|
|
"profile": [
|
|
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Coverage|2.2.0"
|
|
]
|
|
},
|
|
"identifier": [{"system": v3.US_MBI, "value": "M"}],
|
|
}
|
|
)
|
|
assert (
|
|
c.subscriber_id == "M" and c.class_plan is None and c.period_start is None
|
|
)
|
|
|
|
|
|
# ── ExplanationOfBenefit ─────────────────────────────────────
|
|
|
|
|
|
def _si_bb(category: str, **body: object) -> dict:
|
|
d = {
|
|
"category": {
|
|
"coding": [
|
|
{"system": v3.CS_SI, "code": category},
|
|
{
|
|
"system": "http://terminology.hl7.org/CodeSystem/claiminformationcategory",
|
|
"code": "info",
|
|
},
|
|
]
|
|
}
|
|
}
|
|
d.update(body)
|
|
return d
|
|
|
|
|
|
def _si_c4bb(category: str, **body: object) -> dict:
|
|
d = {"category": {"coding": [{"system": v3.C4BB_SI, "code": category}]}}
|
|
d.update(body)
|
|
return d
|
|
|
|
|
|
def _coded(system: str, value: str) -> dict:
|
|
return {"code": {"coding": [{"system": system, "code": value}]}}
|
|
|
|
|
|
def _adj(
|
|
code: str,
|
|
*,
|
|
amount: float | None = None,
|
|
value: float | None = None,
|
|
system: str = v3.CS_ADJ,
|
|
) -> dict:
|
|
d: dict = {"category": {"coding": [{"system": system, "code": code}]}}
|
|
if amount is not None:
|
|
d["amount"] = {"value": amount, "currency": "USD"}
|
|
if value is not None:
|
|
d["value"] = value
|
|
return d
|
|
|
|
|
|
def _eob(**over: object) -> dict:
|
|
base = {
|
|
"resourceType": "ExplanationOfBenefit",
|
|
"id": "-100",
|
|
"meta": {
|
|
"lastUpdated": "2026-02-02T00:00:00Z",
|
|
"source": "NCH",
|
|
"profile": [
|
|
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-ExplanationOfBenefit-Inpatient-Institutional|2.2.0"
|
|
],
|
|
"tag": [
|
|
{"system": v3.CS_SYSTEM_TYPE, "code": "NationalClaimsHistory"},
|
|
{"system": v3.CS_FINAL_ACTION, "code": "FinalAction"},
|
|
],
|
|
},
|
|
"identifier": [
|
|
{
|
|
"type": {"coding": [{"system": v3.C4BB_ID_TYPE, "code": "uc"}]},
|
|
"value": "-100",
|
|
},
|
|
{"system": v3.ID_CLM_CNTL, "value": "CCN-1"},
|
|
],
|
|
"related": [
|
|
{"reference": {"system": v3.ID_CLM_CNTL, "value": "CCN-0"}},
|
|
{"reference": {"system": "x", "value": "no"}},
|
|
],
|
|
"type": {
|
|
"coding": [
|
|
{
|
|
"system": "http://terminology.hl7.org/CodeSystem/claim-type",
|
|
"code": "institutional",
|
|
},
|
|
{"system": v3.CS_CLM_TYPE, "code": "60"},
|
|
{"system": v3.CS_EOB_TYPE, "code": "INPATIENT"},
|
|
]
|
|
},
|
|
"subType": {"coding": [{"code": "inpatient"}]},
|
|
"outcome": "complete",
|
|
"patient": {"reference": "Patient/-7"},
|
|
"billablePeriod": {"start": "2024-03-01", "end": "2024-03-10"},
|
|
"created": "2024-04-01T00:00:00Z",
|
|
"payment": {"amount": {"value": 1000.5}, "date": "2024-04-02"},
|
|
"provider": {"reference": "#billing"},
|
|
"contained": [
|
|
{
|
|
"resourceType": "Organization",
|
|
"id": "billing",
|
|
"name": "General Hospital",
|
|
"identifier": [
|
|
{"system": v3.US_NPI, "value": "1234567893"},
|
|
{"system": v3.CCN, "value": "450001"},
|
|
{"system": v3.TAX_ID, "value": "99-1234567"},
|
|
{"system": "http://" + v3.GENERIC_ID, "value": "GEN1"},
|
|
],
|
|
"address": [{"postalCode": "77550"}],
|
|
}
|
|
],
|
|
"careTeam": [
|
|
{
|
|
"role": {"coding": [{"code": "attending"}]},
|
|
"provider": {"identifier": {"system": v3.US_NPI, "value": "ATT"}},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "operating"}]},
|
|
"provider": {"identifier": {"system": v3.US_NPI, "value": "OPR"}},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "supervisor"}]},
|
|
"provider": {"identifier": {"system": v3.US_NPI, "value": "SUP"}},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "rendering"}]},
|
|
"provider": {"identifier": {"system": v3.US_NPI, "value": "RND"}},
|
|
"qualification": {
|
|
"coding": [{"system": CS + "CLM-PRVDR-SPCLTY-CD", "code": "61"}]
|
|
},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "referring"}]},
|
|
"provider": {"identifier": {"system": v3.US_NPI, "value": "REF"}},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "prescribing"}]},
|
|
"provider": {"identifier": {"system": v3.US_NPI, "value": "PRS"}},
|
|
},
|
|
{
|
|
"role": {"coding": [{"code": "service"}]},
|
|
"provider": {"identifier": {"system": "other", "value": "SVC"}},
|
|
},
|
|
],
|
|
"diagnosis": [
|
|
{
|
|
"sequence": 1,
|
|
"diagnosisCodeableConcept": {
|
|
"coding": [
|
|
{"system": "http://hl7.org/fhir/sid/icd-10-cm", "code": "A00"}
|
|
]
|
|
},
|
|
"type": [{"coding": [{"code": "principal"}]}],
|
|
"onAdmission": {"coding": [{"code": "Y"}]},
|
|
},
|
|
{
|
|
"sequence": 2,
|
|
"diagnosisCodeableConcept": {
|
|
"coding": [
|
|
{"system": "http://hl7.org/fhir/sid/icd-10-cm", "code": "B00"}
|
|
]
|
|
},
|
|
"type": [{"coding": [{"code": "admitting"}]}],
|
|
},
|
|
{"sequence": 13, "diagnosisCodeableConcept": {"coding": [{"code": "Z99"}]}},
|
|
{
|
|
"diagnosisCodeableConcept": {
|
|
"coding": [
|
|
{"system": "http://hl7.org/fhir/sid/icd-9-cm", "code": "9"}
|
|
]
|
|
}
|
|
},
|
|
],
|
|
"procedure": [
|
|
{
|
|
"sequence": 1,
|
|
"date": "2024-03-02",
|
|
"procedureCodeableConcept": {"coding": [{"code": "5A1945Z"}]},
|
|
}
|
|
],
|
|
"supportingInfo": [
|
|
_si_bb("CLM_NRLN_RIC_CD", **_coded(CS + "CLM-NRLN-RIC-CD", "V")),
|
|
_si_bb("CLM_QUERY_CD", **_coded(CS + "CLM-QUERY-CD", "3")),
|
|
_si_bb("CLM_IDR_LD_DT", timingDate="2024-05-01"),
|
|
_si_bb("CLM_SBMTR_CNTRCT_NUM", valueString="H1234"),
|
|
_si_bb("CLM_BLOOD_PT_FRNSH_QTY", valueQuantity={"value": 2}),
|
|
_si_bb("CLM_CNTRCTR_NUM", **_coded(CS + "CLM-CNTRCTR-NUM", "10311")),
|
|
_si_c4bb(
|
|
"admissionperiod",
|
|
timingPeriod={"start": "2024-03-01", "end": "2024-03-10"},
|
|
),
|
|
_si_c4bb("clmrecvddate", timingDate="2024-03-12"),
|
|
_si_c4bb("discharge-status", **_coded(CS + "BENE-PTNT-STUS-CD", "01")),
|
|
_si_c4bb("drg", **_coded("https://www.cms.gov/.../MS-DRG", "470")),
|
|
_si_c4bb("dayssupply", valueQuantity={"value": 30}),
|
|
_si_c4bb(
|
|
"typeofbill",
|
|
code={
|
|
"coding": [
|
|
{
|
|
"system": "https://www.nubc.org/CodeSystem/TypeOfBill",
|
|
"code": "0111",
|
|
},
|
|
{"system": CS + "CLM-BILL-FAC-TYPE-CD", "code": "1"},
|
|
{"system": CS + "CLM-BILL-CLSFCTN-CD", "code": "1"},
|
|
{"system": CS + "CLM-BILL-FREQ-CD", "code": "1"},
|
|
]
|
|
},
|
|
),
|
|
],
|
|
"total": [
|
|
_adj("CLM_SBMT_CHRG_AMT", amount=5000),
|
|
_adj("CLM_BENE_PMT_AMT", amount=20),
|
|
],
|
|
"adjudication": [
|
|
{
|
|
"category": {
|
|
"coding": [
|
|
{"system": v3.C4BB_ADJ_DISC, "code": "benefitpaymentstatus"}
|
|
]
|
|
},
|
|
"reason": {"coding": [{"code": "innetwork"}]},
|
|
},
|
|
_adj("CLM_OPRTNL_IME_AMT", amount=132),
|
|
_adj("CLM_INSTNL_CVRD_DAY_CNT", value=9),
|
|
],
|
|
"item": [
|
|
{
|
|
"sequence": 1,
|
|
"diagnosisSequence": [2],
|
|
"servicedPeriod": {"start": "2024-03-01", "end": "2024-03-02"},
|
|
"productOrService": {
|
|
"coding": [
|
|
{
|
|
"system": "https://www.cms.gov/Medicare/Coding/HCPCSReleaseCodeSets",
|
|
"code": "G0001",
|
|
},
|
|
{
|
|
"system": "https://www.cms.gov/x/HIPPSCodes",
|
|
"code": "HIPPS1",
|
|
},
|
|
]
|
|
},
|
|
"modifier": [
|
|
{"coding": [{"code": "25"}]},
|
|
{"coding": [{"code": "59"}]},
|
|
],
|
|
"revenue": {
|
|
"coding": [{"system": CS + "CLM-REV-CNTR-CD", "code": "0450"}]
|
|
},
|
|
"locationCodeableConcept": {
|
|
"coding": [
|
|
{
|
|
"system": "https://www.cms.gov/Medicare/Coding/place-of-service-codes/Place_of_Service_Code_Set",
|
|
"code": "11",
|
|
}
|
|
]
|
|
},
|
|
"quantity": {"value": 3},
|
|
"extension": [
|
|
{"url": SD + "CLM-REV-CNTR-STUS-CD", "valueCoding": {"code": "S"}},
|
|
{"url": SD + "CLM-LINE-PRFNL-MTUS-CNT", "valueDecimal": 2.5},
|
|
{"url": SD + "CLM-PRVDR-TAX-NUM", "valueString": "TAX1"},
|
|
{"url": SD + "CLM-PRVDR-TYPE-CD", "valueCoding": {"code": "7"}},
|
|
{
|
|
"url": SD + "CLM-RNDRG-PRVDR-PRTCPTG-CD",
|
|
"valueCoding": {"code": "1"},
|
|
},
|
|
],
|
|
"adjudication": [
|
|
_adj("CLM_LINE_CVRD_PD_AMT", amount=10),
|
|
_adj("CLM_LINE_MDCR_DDCTBL_AMT", amount=1),
|
|
{
|
|
"category": {"coding": [{"code": "x"}]},
|
|
"reason": {
|
|
"coding": [
|
|
{"system": v3.CS_ANSI_RSN, "code": "45"},
|
|
{"system": v3.CS_ANSI_GRP, "code": "CO"},
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"category": {"coding": [{"code": "x"}]},
|
|
"reason": {
|
|
"coding": [{"system": v3.CS_ANSI_GRP, "code": "PR"}]
|
|
},
|
|
},
|
|
{
|
|
"category": {"coding": [{"code": "x"}]},
|
|
"reason": {"coding": [{"system": v3.CS_ANSI_RSN, "code": "1"}]},
|
|
},
|
|
{
|
|
"category": {"coding": [{"code": "x"}]},
|
|
"reason": {"coding": [{"system": v3.CS_ANSI_RSN, "code": "2"}]},
|
|
},
|
|
{
|
|
"category": {"coding": [{"code": "x"}]},
|
|
"reason": {
|
|
"coding": [{"system": v3.CS_ANSI_RSN, "code": "5th"}]
|
|
},
|
|
},
|
|
{
|
|
"category": {"coding": [{"code": "x"}]},
|
|
"reason": {"coding": [{"code": "none"}]},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
"sequence": 2,
|
|
"servicedDate": "2024-03-05",
|
|
"productOrService": {
|
|
"coding": [
|
|
{"system": "http://www.ama-assn.org/go/cpt", "code": "99213"}
|
|
]
|
|
},
|
|
"detail": [
|
|
{
|
|
"productOrService": {
|
|
"coding": [{"system": v3.NDC, "code": "00001"}]
|
|
},
|
|
"quantity": {"value": 5, "unit": "ML"},
|
|
}
|
|
],
|
|
"revenue": {
|
|
"coding": [
|
|
{
|
|
"system": "https://www.nubc.org/CodeSystem/RevenueCodes",
|
|
"code": "0250",
|
|
}
|
|
]
|
|
},
|
|
"locationCodeableConcept": {"coding": [{"code": "22"}]},
|
|
},
|
|
],
|
|
}
|
|
base.update(over)
|
|
return base
|
|
|
|
|
|
class TestFlattenEobV3:
|
|
def test_identity_and_tags(self) -> None:
|
|
h, items = flatten_eob(_eob())
|
|
assert (h.id, h.clm_id, h.clm_uniq_id, h.bene_id) == (
|
|
"-100",
|
|
"-100",
|
|
"-100",
|
|
"-7",
|
|
)
|
|
assert (h.clm_cntl_num, h.fi_doc_clm_cntl_num, h.carr_clm_cntl_num) == (
|
|
"CCN-1",
|
|
) * 3
|
|
assert h.clm_orig_cntl_num == "CCN-0"
|
|
assert (h.system_type, h.final_action, h.eob_type, h.clm_type_cd) == (
|
|
"NationalClaimsHistory",
|
|
"FinalAction",
|
|
"INPATIENT",
|
|
"60",
|
|
)
|
|
assert (h.clm_src_id, h.outcome, h.clm_sub_type) == (
|
|
"NCH",
|
|
"complete",
|
|
"inpatient",
|
|
)
|
|
assert h.pde_id is None
|
|
assert (h.clm_from_dt, h.clm_thru_dt, h.clm_efctv_dt) == (
|
|
date(2024, 3, 1),
|
|
date(2024, 3, 10),
|
|
date(2024, 4, 1),
|
|
)
|
|
assert (h.clm_pmt_amt, h.clm_pd_dt) == (1000.5, date(2024, 4, 2))
|
|
assert len(items) == 2
|
|
|
|
def test_supporting_info(self) -> None:
|
|
h, _ = flatten_eob(_eob())
|
|
assert h.nch_near_line_rec_ident_cd == "V"
|
|
assert (h.clm_query_cd, h.carr_clm_entry_cd) == ("3", "3")
|
|
assert h.clm_idr_ld_dt == date(2024, 5, 1)
|
|
assert h.clm_sbmtr_cntrct_num == "H1234"
|
|
assert h.nch_blood_pnts_frnshd_qty == 2
|
|
assert (h.fi_num, h.carr_num) == ("10311", "10311")
|
|
assert (h.clm_actv_care_from_dt, h.clm_dschrg_dt) == (
|
|
date(2024, 3, 1),
|
|
date(2024, 3, 10),
|
|
)
|
|
assert h.clm_submsn_dt == date(2024, 3, 12)
|
|
assert h.bene_ptnt_stus_cd == "01"
|
|
assert h.dgns_drg_cd == "470"
|
|
assert h.clm_line_days_suply_qty == 30
|
|
assert (
|
|
h.clm_bill_fac_type_cd,
|
|
h.clm_bill_clsfctn_cd,
|
|
h.clm_srvc_clsfctn_type_cd,
|
|
h.clm_bill_freq_cd,
|
|
) == ("1", "1", "1", "1")
|
|
assert h.clm_bill_type_cd == "0111"
|
|
|
|
def test_c4bb_code_falls_back_to_any_system(self) -> None:
|
|
r = _eob(
|
|
supportingInfo=[
|
|
_si_c4bb("discharge-status", **_coded("urn:other", "30")),
|
|
{
|
|
"category": {},
|
|
"code": {
|
|
"coding": [
|
|
{
|
|
"system": CS + "CLM-MDCR-NCH-PTNT-STUS-IND-CD",
|
|
"code": "C",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
]
|
|
)
|
|
h, _ = flatten_eob(r)
|
|
assert h.bene_ptnt_stus_cd == "30"
|
|
r = _eob(
|
|
supportingInfo=[
|
|
{
|
|
"category": {},
|
|
"code": {
|
|
"coding": [
|
|
{
|
|
"system": CS + "CLM-MDCR-NCH-PTNT-STUS-IND-CD",
|
|
"code": "C",
|
|
},
|
|
{"system": CS + "CLM-OP-SRVC-TYPE-CD", "code": "3"},
|
|
{"system": CS + "CLM-NRLN-RIC-CD", "code": "W"},
|
|
]
|
|
},
|
|
}
|
|
]
|
|
)
|
|
h, _ = flatten_eob(r)
|
|
assert (
|
|
h.bene_ptnt_stus_cd,
|
|
h.clm_op_srvc_type_cd,
|
|
h.nch_near_line_rec_ident_cd,
|
|
) == ("C", "3", "W")
|
|
|
|
def test_amounts(self) -> None:
|
|
h, _ = flatten_eob(_eob())
|
|
assert (h.clm_sbmt_chrg_amt, h.clm_mdcr_instnl_tot_chrg_amt) == (5000, 5000)
|
|
assert h.clm_bene_pmt_amt == 20
|
|
assert (h.clm_oprtnl_ime_amt, h.ime_op_clm_val_amt) == (132, 132)
|
|
assert h.clm_instnl_cvrd_day_cnt == 9
|
|
assert h.clm_prcng_excptn_cd == "innetwork"
|
|
|
|
def test_providers(self) -> None:
|
|
h, _ = flatten_eob(_eob())
|
|
assert (h.carr_clm_blg_npi_num, h.fac_prvdr_npi_num) == (
|
|
"1234567893",
|
|
"1234567893",
|
|
)
|
|
assert h.prvdr_oscar_num == "450001"
|
|
assert h.clm_blg_prvdr_tax_num == "99-1234567"
|
|
assert h.clm_srvc_prvdr_gnrc_id_num == "GEN1"
|
|
assert (h.clm_blg_prvdr_name, h.clm_blg_prvdr_zip5_cd) == (
|
|
"General Hospital",
|
|
"77550",
|
|
)
|
|
assert (h.atndg_prvdr_npi_num, h.oprtg_prvdr_npi_num, h.othr_prvdr_npi_num) == (
|
|
"ATT",
|
|
"OPR",
|
|
"SUP",
|
|
)
|
|
assert (h.rndrg_prvdr_npi_num, h.clm_prvdr_spclty_cd) == ("RND", "61")
|
|
assert (h.ordrg_prvdr_npi_num, h.clm_prsbng_prvdr_gnrc_id_num) == ("REF", "PRS")
|
|
assert (
|
|
h.clm_rndrg_prvdr_tax_num,
|
|
h.rndrg_prvdr_type_cd,
|
|
h.carr_line_prvdr_type_cd,
|
|
h.prtcptng_ind_cd,
|
|
) == ("TAX1", "7", "7", "1")
|
|
|
|
def test_service_provider_fallback_and_practitioner(self) -> None:
|
|
r = _eob(
|
|
contained=[
|
|
{
|
|
"resourceType": "Practitioner",
|
|
"id": "billing",
|
|
"name": [{"family": "Jones", "given": ["C"]}],
|
|
"identifier": [],
|
|
}
|
|
],
|
|
)
|
|
h, _ = flatten_eob(r)
|
|
assert h.clm_blg_prvdr_name == "Jones, C"
|
|
assert (
|
|
h.clm_srvc_prvdr_gnrc_id_num == "SVC"
|
|
) # from the "service" care team role
|
|
assert h.prvdr_oscar_num is None
|
|
h, _ = flatten_eob(
|
|
_eob(provider={"extension": [{"url": "data-absent"}]}, careTeam=[])
|
|
)
|
|
assert h.carr_clm_blg_npi_num is None and h.rndrg_prvdr_npi_num is None
|
|
|
|
def test_diagnoses_and_procedure(self) -> None:
|
|
h, _ = flatten_eob(_eob())
|
|
assert (h.prncpl_dgns_cd, h.admtg_dgns_cd) == ("A00", "B00")
|
|
assert (h.clm_dgns_1_cd, h.clm_dgns_2_cd, h.clm_dgns_12_cd) == (
|
|
"A00",
|
|
"B00",
|
|
None,
|
|
)
|
|
assert h.dgns_prcdr_icd_ind == "9" # last diagnosis seen was ICD-9
|
|
assert h.clm_poa_ind == "Y"
|
|
assert (h.clm_val_sqnc_num, h.clm_prcdr_cd, h.clm_prcdr_prfrm_dt) == (
|
|
"1",
|
|
"5A1945Z",
|
|
date(2024, 3, 2),
|
|
)
|
|
h, _ = flatten_eob(_eob(procedure=[], diagnosis=[]))
|
|
assert h.clm_prcdr_cd is None and h.prncpl_dgns_cd is None
|
|
|
|
def test_items(self) -> None:
|
|
_, items = flatten_eob(_eob())
|
|
a, b = items
|
|
assert a.clm_id == "-100" and a.clm_line_num == 1
|
|
assert (
|
|
a.clm_line_from_dt,
|
|
a.clm_line_thru_dt,
|
|
a.clm_line_instnl_rev_ctr_dt,
|
|
) == (date(2024, 3, 1), date(2024, 3, 2), date(2024, 3, 1))
|
|
assert a.clm_line_hcpcs_cd == "G0001" and a.clm_rev_apc_hipps_cd == "HIPPS1"
|
|
assert (a.hcpcs_1_mdfr_cd, a.hcpcs_2_mdfr_cd, a.hcpcs_3_mdfr_cd) == (
|
|
"25",
|
|
"59",
|
|
None,
|
|
)
|
|
assert a.clm_line_prod_rev_ctr_cd == "0450" and a.clm_pos_cd == "11"
|
|
assert (a.clm_line_srvc_unit_qty, a.rev_cntr_unit_cnt) == (3, 3)
|
|
assert a.clm_line_dgns_cd == "B00"
|
|
assert (
|
|
a.rev_cntr_stus_ind_cd == "S"
|
|
and a.carr_line_mtus_cnt == 2.5
|
|
and a.tax_num == "TAX1"
|
|
)
|
|
assert (a.clm_rndrg_prvdr_type_cd, a.clm_rndrg_prvdr_prtcptg_cd) == ("7", "1")
|
|
assert (a.clm_line_cvrd_pd_amt, a.rev_cntr_pmt_amt) == (10, 10)
|
|
assert (
|
|
a.clm_line_mdcr_ddctbl_amt,
|
|
a.clm_line_bene_ptb_ddctbl_amt,
|
|
a.rev_cntr_cash_ddctbl_amt,
|
|
) == (1, 1, 1)
|
|
assert (a.clm_1_rev_cntr_ansi_rsn_cd, a.clm_1_rev_cntr_ansi_grp_cd) == (
|
|
"45",
|
|
"CO",
|
|
)
|
|
assert (a.clm_2_rev_cntr_ansi_rsn_cd, a.clm_2_rev_cntr_ansi_grp_cd) == (
|
|
None,
|
|
"PR",
|
|
)
|
|
assert (a.clm_3_rev_cntr_ansi_rsn_cd, a.clm_4_rev_cntr_ansi_rsn_cd) == (
|
|
"1",
|
|
"2",
|
|
)
|
|
assert a.hcpcs_betos_cd is None
|
|
# second item: servicedDate, CPT, NDC from detail, revenue fallback, POS fallback
|
|
assert (b.clm_line_from_dt, b.clm_line_thru_dt) == (
|
|
date(2024, 3, 5),
|
|
date(2024, 3, 5),
|
|
)
|
|
assert b.clm_line_hcpcs_cd == "99213" and b.clm_line_ndc_cd == "00001"
|
|
assert (b.clm_line_ndc_qty, b.clm_line_ndc_qty_qlfyr_cd) == (5, "ML")
|
|
assert b.clm_line_prod_rev_ctr_cd == "0250" and b.clm_pos_cd == "22"
|
|
assert b.clm_line_dgns_cd is None and b.clm_line_cvrd_pd_amt is None
|
|
|
|
def test_pharmacy_identity(self) -> None:
|
|
r = _eob(
|
|
type={
|
|
"coding": [
|
|
{"system": v3.CS_EOB_TYPE, "code": "PDE"},
|
|
{"system": v3.CS_CLM_TYPE, "code": "1"},
|
|
]
|
|
},
|
|
item=[
|
|
{
|
|
"sequence": 1,
|
|
"productOrService": {"coding": [{"system": v3.NDC, "code": "123"}]},
|
|
"quantity": {"value": 30, "unit": "EA"},
|
|
"servicedDate": "2024-01-01",
|
|
}
|
|
],
|
|
)
|
|
h, items = flatten_eob(r)
|
|
assert h.pde_id == "-100" and h.eob_type == "PDE"
|
|
assert items[0].clm_line_ndc_cd == "123"
|
|
assert (items[0].clm_line_ndc_qty, items[0].clm_line_ndc_qty_qlfyr_cd) == (
|
|
30,
|
|
"EA",
|
|
)
|
|
|
|
def test_minimal(self) -> None:
|
|
h, items = flatten_eob(
|
|
{"meta": {"tag": [{"system": v3.CS_SYSTEM_TYPE, "code": "DDPS"}]}}
|
|
)
|
|
assert h.system_type == "DDPS" and h.clm_id is None and items == []
|
|
assert h.clm_prcng_excptn_cd is None and h.clm_orig_cntl_num is None
|
|
|
|
|
|
# ── official sample invariants ───────────────────────────────
|
|
|
|
|
|
class TestOfficialSamples:
|
|
def test_every_sample_is_v3(
|
|
self, sample_patients, sample_coverages, sample_eobs
|
|
) -> None:
|
|
assert all(
|
|
v3.is_v3(r) for r in sample_patients + sample_coverages + sample_eobs
|
|
)
|
|
|
|
def test_patients(self, sample_patients) -> None:
|
|
rows = [flatten_patient(r) for r in sample_patients]
|
|
assert len(rows) == 94
|
|
assert all(p.bene_mbi_id for p in rows)
|
|
assert all(p.bene_id == p.id for p in rows)
|
|
assert {p.bene_sex_cd for p in rows} == {"1", "2"}
|
|
assert {p.bene_race_cd for p in rows} <= set("0123456")
|
|
assert all(p.cntct_lang_cd for p in rows)
|
|
|
|
def test_coverages(self, sample_coverages) -> None:
|
|
rows = [flatten_coverage(r) for r in sample_coverages]
|
|
plans = {c.class_plan for c in rows}
|
|
assert plans == {"Part A", "Part B", "Part C", "Dual Medicare/Medicaid"}
|
|
assert all(c.period_start for c in rows)
|
|
part_a = [c for c in rows if c.class_plan == "Part A"]
|
|
assert all(c.ms_cd and c.bene_part_a_enrlmt_bgn_dt for c in part_a)
|
|
dual = [c for c in rows if c.class_plan == "Dual Medicare/Medicaid"]
|
|
assert all(c.dual_stus_cd for c in dual)
|
|
|
|
def test_eobs(self, sample_eobs) -> None:
|
|
heads, items = [], []
|
|
for r in sample_eobs:
|
|
h, lines = flatten_eob(r)
|
|
heads.append(h)
|
|
items.extend(lines)
|
|
assert len(heads) == 269 and len(items) == 1232
|
|
assert all(
|
|
h.clm_id and h.clm_cntl_num and h.system_type and h.eob_type for h in heads
|
|
)
|
|
assert {h.system_type for h in heads} == {"NationalClaimsHistory", "DDPS"}
|
|
pde = [h for h in heads if h.eob_type == "PDE"]
|
|
assert pde and all(
|
|
h.pde_id == h.clm_id and h.clm_line_days_suply_qty is not None for h in pde
|
|
)
|
|
inst = [
|
|
h
|
|
for h in heads
|
|
if h.eob_type in ("INPATIENT", "SNF", "HOSPICE", "HHA", "OUTPATIENT")
|
|
]
|
|
assert inst and all(h.clm_bill_fac_type_cd for h in inst)
|
|
assert all(i.clm_id and i.clm_line_from_dt for i in items)
|
|
assert sum(1 for i in items if i.clm_line_hcpcs_cd) > 1000
|