- Rewrite diagnosis/procedure pivots from 25-iteration progressive joins to conditional aggregation (group_by + when/then/max), eliminating deeply nested SQL that caused sqlglot RecursionError - Fix clm_line_srvc_unit_qty column reference (no _rev suffix needed, column is unique to right side of join) - Move _nullify_sentinel into claim_start_date/admission_date aliases instead of producing extra clm_from_dt column that broke nw.concat schema alignment across institutional/physician/DME claim types - All transpile known failures resolved: 0 remaining
1646 lines
57 KiB
Python
1646 lines
57 KiB
Python
"""Tests for aco.express.cclf -- CCLF-to-input-layer transforms.
|
|
|
|
Tests verify staging, intermediate, and final output functions:
|
|
- MBI resolution via CCLF9 crosswalk
|
|
- Sentinel date nullification
|
|
- ICD indicator mapping
|
|
- Amount negation for cancelled claims
|
|
- ADR (adjustment/dedup/revision) logic
|
|
- Column selection and renaming
|
|
- Row count preservation
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import narwhals as nw
|
|
import polars as pl
|
|
import pytest
|
|
|
|
from aco.express.cclf import (
|
|
_icd_indicator,
|
|
_nullify_sentinel,
|
|
eligibility,
|
|
int_diagnosis_pivot,
|
|
int_dme_claim_adr,
|
|
int_dme_medical_claim,
|
|
int_institutional_header_adr,
|
|
int_institutional_medical_claim,
|
|
int_pharmacy_claim_adr,
|
|
int_physician_claim_adr,
|
|
int_physician_medical_claim,
|
|
int_procedure_pivot,
|
|
medical_claim,
|
|
pharmacy_claim,
|
|
stg_beneficiary_demographics,
|
|
stg_beneficiary_xref,
|
|
stg_dme_claim,
|
|
stg_institutional_header,
|
|
stg_pharmacy_claim,
|
|
stg_physician_claim,
|
|
stg_revenue_center,
|
|
)
|
|
|
|
# ── shared fixtures ──────────────────────────────────────────
|
|
|
|
|
|
@pytest.fixture
|
|
def xref_df() -> pl.DataFrame:
|
|
"""CCLF9 beneficiary crosswalk (raw)."""
|
|
return pl.DataFrame(
|
|
{
|
|
"crnt_num": ["MBI-NEW", "MBI-NEW", "MBI-C"],
|
|
"prvs_num": ["MBI-OLD", "MBI-OLD", "MBI-D"],
|
|
"prvs_id_efctv_dt": [
|
|
"2023-01-01",
|
|
"2022-06-01",
|
|
"2023-03-01",
|
|
],
|
|
}
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def staged_xref(xref_df: pl.DataFrame) -> pl.DataFrame:
|
|
"""Deduplicated xref: one row per prvs_num."""
|
|
return stg_beneficiary_xref(cclf__cclf9=xref_df)
|
|
|
|
|
|
# ── stg_beneficiary_xref ────────────────────────────────────
|
|
|
|
|
|
class TestStgBeneficiaryXref:
|
|
"""CCLF9 crosswalk dedup."""
|
|
|
|
def test_dedup_keeps_latest(self, xref_df: pl.DataFrame) -> None:
|
|
result = stg_beneficiary_xref(cclf__cclf9=xref_df)
|
|
# MBI-OLD appears twice; latest efctv_dt wins
|
|
old_rows = result.filter(pl.col("prvs_num") == "MBI-OLD")
|
|
assert old_rows.shape[0] == 1
|
|
assert old_rows["crnt_num"].to_list()[0] == "MBI-NEW"
|
|
|
|
def test_output_columns(self, xref_df: pl.DataFrame) -> None:
|
|
result = stg_beneficiary_xref(cclf__cclf9=xref_df)
|
|
assert set(result.columns) == {
|
|
"crnt_num",
|
|
"prvs_num",
|
|
}
|
|
|
|
def test_unique_prvs_num(self, xref_df: pl.DataFrame) -> None:
|
|
result = stg_beneficiary_xref(cclf__cclf9=xref_df)
|
|
assert result["prvs_num"].n_unique() == result.shape[0]
|
|
|
|
|
|
# ── stg_institutional_header (CCLF1) ────────────────────────
|
|
|
|
|
|
class TestStgInstitutionalHeader:
|
|
"""CCLF1 staging: MBI join + cancellation negation."""
|
|
|
|
@pytest.fixture
|
|
def cclf1_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"bene_mbi_id": [
|
|
"MBI-OLD",
|
|
"MBI-KEEP",
|
|
],
|
|
"clm_adjsmt_type_cd": ["1", "0"],
|
|
"clm_pmt_amt": [100.0, 200.0],
|
|
"clm_mdcr_instnl_tot_chrg_amt": [
|
|
500.0,
|
|
600.0,
|
|
],
|
|
"cur_clm_uniq_id": ["C1", "C2"],
|
|
"prvdr_oscar_num": ["P1", "P2"],
|
|
"clm_from_dt": [
|
|
"2023-01-01",
|
|
"2023-02-01",
|
|
],
|
|
"clm_thru_dt": [
|
|
"2023-01-10",
|
|
"2023-02-10",
|
|
],
|
|
"dgns_prcdr_icd_ind": ["0", "0"],
|
|
}
|
|
)
|
|
|
|
def test_mbi_resolution(
|
|
self,
|
|
cclf1_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_institutional_header(
|
|
cclf__cclf1=cclf1_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
mbis = result.sort("cur_clm_uniq_id")["current_bene_mbi_id"].to_list()
|
|
# MBI-OLD resolved to MBI-NEW via xref
|
|
assert mbis[0] == "MBI-NEW"
|
|
# MBI-KEEP has no xref match; falls back
|
|
assert mbis[1] == "MBI-KEEP"
|
|
|
|
def test_cancelled_amounts_negated(
|
|
self,
|
|
cclf1_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_institutional_header(
|
|
cclf__cclf1=cclf1_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
cancelled = result.filter(pl.col("clm_adjsmt_type_cd") == "1")
|
|
assert cancelled["clm_pmt_amt"].to_list() == [-100.0]
|
|
assert cancelled["clm_mdcr_instnl_tot_chrg_amt"].to_list() == [-500.0]
|
|
|
|
def test_original_amounts_unchanged(
|
|
self,
|
|
cclf1_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_institutional_header(
|
|
cclf__cclf1=cclf1_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
original = result.filter(pl.col("clm_adjsmt_type_cd") == "0")
|
|
assert original["clm_pmt_amt"].to_list() == [200.0]
|
|
|
|
def test_row_count_preserved(
|
|
self,
|
|
cclf1_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_institutional_header(
|
|
cclf__cclf1=cclf1_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
assert result.shape[0] == cclf1_df.shape[0]
|
|
|
|
|
|
# ── int_institutional_header_adr ─────────────────────────────
|
|
|
|
|
|
class TestIntInstitutionalHeaderAdr:
|
|
"""ADR dedup for CCLF1: keep latest, drop cancelled."""
|
|
|
|
@pytest.fixture
|
|
def staged_header(self) -> pl.DataFrame:
|
|
"""Pre-staged CCLF1 with three related claims.
|
|
|
|
ADR ranks by cur_clm_uniq_id descending within
|
|
the natural-key partition, keeps rank=1 where
|
|
type != '1'. CLM-003 (adjustment) is highest ID
|
|
and non-cancelled, so it survives.
|
|
"""
|
|
return pl.DataFrame(
|
|
{
|
|
"prvdr_oscar_num": ["H1"] * 3,
|
|
"clm_from_dt": ["2023-01-01"] * 3,
|
|
"clm_thru_dt": ["2023-01-10"] * 3,
|
|
"current_bene_mbi_id": ["MBI-A"] * 3,
|
|
"cur_clm_uniq_id": [
|
|
"CLM-001",
|
|
"CLM-002",
|
|
"CLM-003",
|
|
],
|
|
"clm_adjsmt_type_cd": ["0", "1", "2"],
|
|
"clm_pmt_amt": [
|
|
100.0,
|
|
-100.0,
|
|
120.0,
|
|
],
|
|
}
|
|
)
|
|
|
|
def test_keeps_latest_non_cancelled(self, staged_header: pl.DataFrame) -> None:
|
|
result = int_institutional_header_adr(
|
|
cclf___stg_institutional_header=staged_header,
|
|
)
|
|
# CLM-003 is highest ID and type='2' (adj); wins
|
|
assert result.shape[0] == 1
|
|
assert result["cur_clm_uniq_id"].to_list()[0] == "CLM-003"
|
|
|
|
def test_drops_rn_column(self, staged_header: pl.DataFrame) -> None:
|
|
result = int_institutional_header_adr(
|
|
cclf___stg_institutional_header=staged_header,
|
|
)
|
|
assert "_rn" not in result.columns
|
|
|
|
def test_all_cancelled_yields_empty(self) -> None:
|
|
df = pl.DataFrame(
|
|
{
|
|
"prvdr_oscar_num": ["H1", "H1"],
|
|
"clm_from_dt": [
|
|
"2023-01-01",
|
|
"2023-01-01",
|
|
],
|
|
"clm_thru_dt": [
|
|
"2023-01-10",
|
|
"2023-01-10",
|
|
],
|
|
"current_bene_mbi_id": [
|
|
"MBI-A",
|
|
"MBI-A",
|
|
],
|
|
"cur_clm_uniq_id": [
|
|
"CLM-001",
|
|
"CLM-002",
|
|
],
|
|
"clm_adjsmt_type_cd": ["1", "1"],
|
|
"clm_pmt_amt": [-100.0, -200.0],
|
|
}
|
|
)
|
|
result = int_institutional_header_adr(
|
|
cclf___stg_institutional_header=df,
|
|
)
|
|
assert result.shape[0] == 0
|
|
|
|
|
|
# ── stg_physician_claim (CCLF5) ─────────────────────────────
|
|
|
|
|
|
class TestStgPhysicianClaim:
|
|
"""CCLF5 staging: MBI join + cancellation negation."""
|
|
|
|
@pytest.fixture
|
|
def cclf5_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"bene_mbi_id": [
|
|
"MBI-OLD",
|
|
"MBI-X",
|
|
],
|
|
"clm_adjsmt_type_cd": ["1", "0"],
|
|
"clm_line_cvrd_pd_amt": [
|
|
50.0,
|
|
75.0,
|
|
],
|
|
"clm_line_alowd_chrg_amt": [
|
|
80.0,
|
|
120.0,
|
|
],
|
|
"cur_clm_uniq_id": ["C10", "C11"],
|
|
"rndrg_prvdr_npi_num": [
|
|
"NPI1",
|
|
"NPI2",
|
|
],
|
|
"clm_from_dt": [
|
|
"2023-03-01",
|
|
"2023-04-01",
|
|
],
|
|
"clm_thru_dt": [
|
|
"2023-03-05",
|
|
"2023-04-05",
|
|
],
|
|
"dgns_prcdr_icd_ind": ["0", "9"],
|
|
}
|
|
)
|
|
|
|
def test_mbi_resolution(
|
|
self,
|
|
cclf5_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_physician_claim(
|
|
cclf__cclf5=cclf5_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
mbis = result.sort("cur_clm_uniq_id")["current_bene_mbi_id"].to_list()
|
|
assert mbis[0] == "MBI-NEW"
|
|
assert mbis[1] == "MBI-X"
|
|
|
|
def test_cancelled_amounts_negated(
|
|
self,
|
|
cclf5_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_physician_claim(
|
|
cclf__cclf5=cclf5_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
cancelled = result.filter(pl.col("clm_adjsmt_type_cd") == "1")
|
|
assert cancelled["clm_line_cvrd_pd_amt"].to_list() == [-50.0]
|
|
assert cancelled["clm_line_alowd_chrg_amt"].to_list() == [-80.0]
|
|
|
|
def test_original_amounts_unchanged(
|
|
self,
|
|
cclf5_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_physician_claim(
|
|
cclf__cclf5=cclf5_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
original = result.filter(pl.col("clm_adjsmt_type_cd") == "0")
|
|
assert original["clm_line_cvrd_pd_amt"].to_list() == [75.0]
|
|
|
|
def test_row_count_preserved(
|
|
self,
|
|
cclf5_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_physician_claim(
|
|
cclf__cclf5=cclf5_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
assert result.shape[0] == cclf5_df.shape[0]
|
|
|
|
|
|
# ── int_physician_claim_adr ──────────────────────────────────
|
|
|
|
|
|
class TestIntPhysicianClaimAdr:
|
|
"""ADR dedup for CCLF5."""
|
|
|
|
@pytest.fixture
|
|
def staged_cclf5(self) -> pl.DataFrame:
|
|
"""Ranked by cur_clm_uniq_id desc; C12 is latest
|
|
and non-cancelled (type='2'), so it survives ADR.
|
|
"""
|
|
return pl.DataFrame(
|
|
{
|
|
"rndrg_prvdr_npi_num": ["NPI1"] * 3,
|
|
"clm_from_dt": ["2023-03-01"] * 3,
|
|
"clm_thru_dt": ["2023-03-05"] * 3,
|
|
"current_bene_mbi_id": ["MBI-A"] * 3,
|
|
"cur_clm_uniq_id": [
|
|
"C10",
|
|
"C11",
|
|
"C12",
|
|
],
|
|
"clm_adjsmt_type_cd": ["0", "1", "2"],
|
|
"clm_line_cvrd_pd_amt": [
|
|
50.0,
|
|
-50.0,
|
|
55.0,
|
|
],
|
|
}
|
|
)
|
|
|
|
def test_keeps_latest_non_cancelled(self, staged_cclf5: pl.DataFrame) -> None:
|
|
result = int_physician_claim_adr(
|
|
cclf___stg_physician_claim=staged_cclf5,
|
|
)
|
|
assert result.shape[0] == 1
|
|
assert result["cur_clm_uniq_id"].to_list()[0] == "C12"
|
|
|
|
def test_drops_rn_column(self, staged_cclf5: pl.DataFrame) -> None:
|
|
result = int_physician_claim_adr(
|
|
cclf___stg_physician_claim=staged_cclf5,
|
|
)
|
|
assert "_rn" not in result.columns
|
|
|
|
|
|
# ── stg_pharmacy_claim (CCLF7) ───────────────────────────────
|
|
|
|
|
|
class TestStgPharmacyClaim:
|
|
"""CCLF7 staging: MBI join."""
|
|
|
|
@pytest.fixture
|
|
def cclf7_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"bene_mbi_id": [
|
|
"MBI-OLD",
|
|
"MBI-Z",
|
|
],
|
|
"cur_clm_uniq_id": ["RX1", "RX2"],
|
|
"clm_adjsmt_type_cd": ["0", "0"],
|
|
"clm_line_ndc_cd": [
|
|
"12345678901",
|
|
"98765432101",
|
|
],
|
|
"clm_line_from_dt": [
|
|
"2023-05-01",
|
|
"2023-06-01",
|
|
],
|
|
"clm_line_srvc_unit_qty": [
|
|
"30",
|
|
"60",
|
|
],
|
|
"clm_line_days_suply_qty": [
|
|
"30",
|
|
"90",
|
|
],
|
|
"clm_line_rx_fill_num": ["0", "1"],
|
|
"clm_line_bene_pmt_amt": [
|
|
10.0,
|
|
25.0,
|
|
],
|
|
"prvdr_srvc_id_qlfyr_cd": [
|
|
"01",
|
|
"06",
|
|
],
|
|
"clm_srvc_prvdr_gnrc_id_num": [
|
|
"NPI-DISP",
|
|
"UPIN-DISP",
|
|
],
|
|
"prvdr_prsbng_id_qlfyr_cd": [
|
|
"01",
|
|
"01",
|
|
],
|
|
"clm_prsbng_prvdr_gnrc_id_num": [
|
|
"NPI-PRSC",
|
|
"NPI-PRSC2",
|
|
],
|
|
}
|
|
)
|
|
|
|
def test_mbi_resolution(
|
|
self,
|
|
cclf7_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_pharmacy_claim(
|
|
cclf__cclf7=cclf7_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
mbis = result.sort("cur_clm_uniq_id")["current_bene_mbi_id"].to_list()
|
|
assert mbis[0] == "MBI-NEW"
|
|
assert mbis[1] == "MBI-Z"
|
|
|
|
def test_row_count_preserved(
|
|
self,
|
|
cclf7_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_pharmacy_claim(
|
|
cclf__cclf7=cclf7_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
assert result.shape[0] == cclf7_df.shape[0]
|
|
|
|
|
|
# ── int_pharmacy_claim_adr ───────────────────────────────────
|
|
|
|
|
|
class TestIntPharmacyClaimAdr:
|
|
"""ADR dedup for CCLF7."""
|
|
|
|
@pytest.fixture
|
|
def staged_cclf7(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": [
|
|
"RX1",
|
|
"RX1",
|
|
"RX1",
|
|
],
|
|
"current_bene_mbi_id": [
|
|
"MBI-A",
|
|
"MBI-A",
|
|
"MBI-A",
|
|
],
|
|
"clm_adjsmt_type_cd": ["0", "2", "1"],
|
|
"clm_line_ndc_cd": [
|
|
"NDC1",
|
|
"NDC1",
|
|
"NDC1",
|
|
],
|
|
"clm_line_bene_pmt_amt": [
|
|
10.0,
|
|
12.0,
|
|
0.0,
|
|
],
|
|
}
|
|
)
|
|
|
|
def test_keeps_latest_non_cancelled(self, staged_cclf7: pl.DataFrame) -> None:
|
|
result = int_pharmacy_claim_adr(
|
|
cclf___stg_pharmacy_claim=staged_cclf7,
|
|
)
|
|
assert result.shape[0] == 1
|
|
assert result["clm_adjsmt_type_cd"].to_list()[0] == "2"
|
|
|
|
def test_all_cancelled_yields_empty(self) -> None:
|
|
df = pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["RX1", "RX1"],
|
|
"current_bene_mbi_id": [
|
|
"MBI-A",
|
|
"MBI-A",
|
|
],
|
|
"clm_adjsmt_type_cd": ["1", "1"],
|
|
"clm_line_ndc_cd": ["NDC1", "NDC1"],
|
|
"clm_line_bene_pmt_amt": [0.0, 0.0],
|
|
}
|
|
)
|
|
result = int_pharmacy_claim_adr(
|
|
cclf___stg_pharmacy_claim=df,
|
|
)
|
|
assert result.shape[0] == 0
|
|
|
|
|
|
# ── pharmacy_claim (final) ───────────────────────────────────
|
|
|
|
|
|
class TestPharmacyClaim:
|
|
"""CCLF7 -> pharmacy_claim output mapping."""
|
|
|
|
@pytest.fixture
|
|
def adr_cclf7(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["RX1"],
|
|
"current_bene_mbi_id": ["MBI-A"],
|
|
"clm_adjsmt_type_cd": ["0"],
|
|
"clm_line_ndc_cd": ["12345678901"],
|
|
"clm_line_from_dt": ["2023-05-01"],
|
|
"clm_line_srvc_unit_qty": ["30"],
|
|
"clm_line_days_suply_qty": ["30"],
|
|
"clm_line_rx_fill_num": ["0"],
|
|
"clm_line_bene_pmt_amt": [10.0],
|
|
"prvdr_srvc_id_qlfyr_cd": ["01"],
|
|
"clm_srvc_prvdr_gnrc_id_num": ["1234567890"],
|
|
"prvdr_prsbng_id_qlfyr_cd": ["01"],
|
|
"clm_prsbng_prvdr_gnrc_id_num": ["9876543210"],
|
|
}
|
|
)
|
|
|
|
def test_column_mapping(self, adr_cclf7: pl.DataFrame) -> None:
|
|
result = pharmacy_claim(
|
|
cclf___int_pharmacy_claim_adr=adr_cclf7,
|
|
)
|
|
assert result["claim_id"].to_list() == ["RX1"]
|
|
assert result["person_id"].to_list() == ["MBI-A"]
|
|
assert result["member_id"].to_list() == ["MBI-A"]
|
|
assert result["ndc_code"].to_list() == ["12345678901"]
|
|
assert result["payer"].to_list() == ["medicare"]
|
|
assert result["data_source"].to_list() == ["medicare cclf"]
|
|
|
|
def test_npi_qualifier_filtering(self, adr_cclf7: pl.DataFrame) -> None:
|
|
result = pharmacy_claim(
|
|
cclf___int_pharmacy_claim_adr=adr_cclf7,
|
|
)
|
|
# qualifier = '01' means NPI; should be present
|
|
assert result["prescribing_provider_npi"].to_list() == ["9876543210"]
|
|
assert result["dispensing_provider_npi"].to_list() == ["1234567890"]
|
|
|
|
def test_npi_qualifier_non_npi_nulled(self) -> None:
|
|
"""Non-NPI qualifiers should produce null."""
|
|
df = pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["RX2"],
|
|
"current_bene_mbi_id": ["MBI-B"],
|
|
"clm_adjsmt_type_cd": ["0"],
|
|
"clm_line_ndc_cd": ["99999999999"],
|
|
"clm_line_from_dt": ["2023-06-01"],
|
|
"clm_line_srvc_unit_qty": ["60"],
|
|
"clm_line_days_suply_qty": ["90"],
|
|
"clm_line_rx_fill_num": ["1"],
|
|
"clm_line_bene_pmt_amt": [25.0],
|
|
"prvdr_srvc_id_qlfyr_cd": ["06"],
|
|
"clm_srvc_prvdr_gnrc_id_num": ["UPIN123"],
|
|
"prvdr_prsbng_id_qlfyr_cd": ["07"],
|
|
"clm_prsbng_prvdr_gnrc_id_num": ["NCPDP456"],
|
|
}
|
|
)
|
|
result = pharmacy_claim(
|
|
cclf___int_pharmacy_claim_adr=df,
|
|
)
|
|
assert result["dispensing_provider_npi"].to_list() == [None]
|
|
assert result["prescribing_provider_npi"].to_list() == [None]
|
|
|
|
def test_paid_and_copay_same(self, adr_cclf7: pl.DataFrame) -> None:
|
|
result = pharmacy_claim(
|
|
cclf___int_pharmacy_claim_adr=adr_cclf7,
|
|
)
|
|
assert result["paid_amount"].to_list() == [10.0]
|
|
assert result["copayment_amount"].to_list() == [10.0]
|
|
|
|
def test_null_amount_columns(self, adr_cclf7: pl.DataFrame) -> None:
|
|
result = pharmacy_claim(
|
|
cclf___int_pharmacy_claim_adr=adr_cclf7,
|
|
)
|
|
for col in (
|
|
"allowed_amount",
|
|
"charge_amount",
|
|
"coinsurance_amount",
|
|
"deductible_amount",
|
|
):
|
|
assert result[col].to_list() == [None]
|
|
|
|
|
|
# ── stg_beneficiary_demographics (CCLF8) ────────────────────
|
|
|
|
|
|
class TestStgBeneficiaryDemographics:
|
|
"""CCLF8 staging: MBI join + dedup."""
|
|
|
|
@pytest.fixture
|
|
def cclf8_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"bene_mbi_id": [
|
|
"MBI-OLD",
|
|
"MBI-OLD",
|
|
"MBI-Y",
|
|
],
|
|
"bene_sex_cd": ["1", "1", "2"],
|
|
"bene_race_cd": ["1", "1", "2"],
|
|
"bene_dob": [
|
|
"1950-01-15",
|
|
"1950-01-15",
|
|
"1960-03-20",
|
|
],
|
|
"bene_death_dt": [None, None, None],
|
|
"bene_rng_bgn_dt": [
|
|
"2023-01-01",
|
|
"2023-01-01",
|
|
"2023-02-01",
|
|
],
|
|
"bene_rng_end_dt": [
|
|
"2023-12-31",
|
|
"2023-12-31",
|
|
"2023-12-31",
|
|
],
|
|
"bene_orgnl_entlmt_rsn_cd": [
|
|
"0",
|
|
"0",
|
|
"1",
|
|
],
|
|
"bene_dual_stus_cd": [
|
|
"00",
|
|
"00",
|
|
"01",
|
|
],
|
|
"bene_mdcr_stus_cd": [
|
|
"10",
|
|
"10",
|
|
"20",
|
|
],
|
|
"bene_1st_name": [
|
|
"JOHN",
|
|
"JOHN",
|
|
"JANE",
|
|
],
|
|
"bene_midl_name": ["A", "A", "B"],
|
|
"bene_last_name": [
|
|
"DOE",
|
|
"DOE",
|
|
"SMITH",
|
|
],
|
|
"bene_line_1_adr": [
|
|
"123 ELM",
|
|
"123 ELM",
|
|
"456 OAK",
|
|
],
|
|
"geo_zip_plc_name": [
|
|
"SPRINGFIELD",
|
|
"SPRINGFIELD",
|
|
"SHELBYVILLE",
|
|
],
|
|
"geo_usps_state_cd": ["IL", "IL", "IL"],
|
|
"geo_zip5_cd": [
|
|
"62701",
|
|
"62701",
|
|
"62565",
|
|
],
|
|
}
|
|
)
|
|
|
|
def test_dedup_on_resolved_mbi(
|
|
self,
|
|
cclf8_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_beneficiary_demographics(
|
|
cclf__cclf8=cclf8_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
# Two MBI-OLD rows resolve to MBI-NEW, deduped
|
|
assert result.shape[0] == 2
|
|
|
|
def test_mbi_resolution(
|
|
self,
|
|
cclf8_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_beneficiary_demographics(
|
|
cclf__cclf8=cclf8_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
mbis = sorted(result["current_bene_mbi_id"].to_list())
|
|
assert "MBI-NEW" in mbis
|
|
assert "MBI-Y" in mbis
|
|
|
|
|
|
# ── eligibility (final) ──────────────────────────────────────
|
|
|
|
|
|
class TestEligibility:
|
|
"""CCLF8 -> eligibility output with crosswalks."""
|
|
|
|
@pytest.fixture
|
|
def staged_cclf8(self) -> pl.DataFrame:
|
|
"""Pre-staged, deduped CCLF8."""
|
|
return pl.DataFrame(
|
|
{
|
|
"current_bene_mbi_id": [
|
|
"MBI-A",
|
|
"MBI-B",
|
|
"MBI-C",
|
|
],
|
|
"bene_sex_cd": ["1", "2", "0"],
|
|
"bene_race_cd": ["1", "2", "5"],
|
|
"bene_dob": [
|
|
"1950-01-15",
|
|
"1960-03-20",
|
|
"1970-07-04",
|
|
],
|
|
"bene_death_dt": [
|
|
"2023-11-01",
|
|
None,
|
|
None,
|
|
],
|
|
"bene_rng_bgn_dt": [
|
|
"2023-01-01",
|
|
"2023-02-01",
|
|
"2023-03-01",
|
|
],
|
|
"bene_rng_end_dt": [
|
|
"2023-12-31",
|
|
"2023-12-31",
|
|
"2023-12-31",
|
|
],
|
|
"bene_orgnl_entlmt_rsn_cd": [
|
|
"0",
|
|
"1",
|
|
"2",
|
|
],
|
|
"bene_dual_stus_cd": [
|
|
"00",
|
|
"01",
|
|
"02",
|
|
],
|
|
"bene_mdcr_stus_cd": [
|
|
"10",
|
|
"20",
|
|
"30",
|
|
],
|
|
"bene_1st_name": [
|
|
"JOHN",
|
|
"JANE",
|
|
"BOB",
|
|
],
|
|
"bene_midl_name": ["A", "B", "C"],
|
|
"bene_last_name": [
|
|
"DOE",
|
|
"SMITH",
|
|
"JONES",
|
|
],
|
|
"bene_line_1_adr": [
|
|
"123 ELM",
|
|
"456 OAK",
|
|
"789 PINE",
|
|
],
|
|
"geo_zip_plc_name": [
|
|
"SPRINGFIELD",
|
|
"SHELBYVILLE",
|
|
"CAPITAL CITY",
|
|
],
|
|
"geo_usps_state_cd": [
|
|
"IL",
|
|
"IL",
|
|
"IL",
|
|
],
|
|
"geo_zip5_cd": [
|
|
"62701",
|
|
"62565",
|
|
"62700",
|
|
],
|
|
}
|
|
)
|
|
|
|
def test_gender_crosswalk(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
genders = result.sort("person_id")["gender"].to_list()
|
|
assert genders == [
|
|
"male",
|
|
"female",
|
|
"unknown",
|
|
]
|
|
|
|
def test_race_crosswalk(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
races = result.sort("person_id")["race"].to_list()
|
|
assert races == ["white", "black", "hispanic"]
|
|
|
|
def test_death_flag(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
flags = result.sort("person_id")["death_flag"].to_list()
|
|
# MBI-A has death_dt, others don't
|
|
assert flags == [1, 0, 0]
|
|
|
|
def test_person_member_id_match(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
assert result["person_id"].to_list() == result["member_id"].to_list()
|
|
|
|
def test_payer_fields(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
for col in ("payer", "payer_type", "plan"):
|
|
vals = result[col].unique().to_list()
|
|
assert vals == ["medicare"]
|
|
|
|
def test_data_source(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
vals = result["data_source"].unique().to_list()
|
|
assert vals == ["medicare cclf"]
|
|
|
|
def test_name_fields(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
row = result.filter(pl.col("person_id") == "MBI-A")
|
|
assert row["first_name"].to_list() == ["JOHN"]
|
|
assert row["last_name"].to_list() == ["DOE"]
|
|
|
|
def test_address_fields(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
row = result.filter(pl.col("person_id") == "MBI-B")
|
|
assert row["city"].to_list() == ["SHELBYVILLE"]
|
|
assert row["state"].to_list() == ["IL"]
|
|
assert row["zip_code"].to_list() == ["62565"]
|
|
|
|
def test_row_count_preserved(self, staged_cclf8: pl.DataFrame) -> None:
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=staged_cclf8,
|
|
)
|
|
assert result.shape[0] == staged_cclf8.shape[0]
|
|
|
|
def test_race_all_codes(self) -> None:
|
|
"""Exercise all 7 race code mappings."""
|
|
df = pl.DataFrame(
|
|
{
|
|
"current_bene_mbi_id": [f"M{i}" for i in range(7)],
|
|
"bene_sex_cd": ["1"] * 7,
|
|
"bene_race_cd": [
|
|
"0",
|
|
"1",
|
|
"2",
|
|
"3",
|
|
"4",
|
|
"5",
|
|
"6",
|
|
],
|
|
"bene_dob": ["1950-01-01"] * 7,
|
|
"bene_death_dt": [None] * 7,
|
|
"bene_rng_bgn_dt": ["2023-01-01"] * 7,
|
|
"bene_rng_end_dt": ["2023-12-31"] * 7,
|
|
"bene_orgnl_entlmt_rsn_cd": ["0"] * 7,
|
|
"bene_dual_stus_cd": ["00"] * 7,
|
|
"bene_mdcr_stus_cd": ["10"] * 7,
|
|
"bene_1st_name": ["A"] * 7,
|
|
"bene_midl_name": ["B"] * 7,
|
|
"bene_last_name": ["C"] * 7,
|
|
"bene_line_1_adr": ["ADDR"] * 7,
|
|
"geo_zip_plc_name": ["CITY"] * 7,
|
|
"geo_usps_state_cd": ["IL"] * 7,
|
|
"geo_zip5_cd": ["60601"] * 7,
|
|
}
|
|
)
|
|
result = eligibility(
|
|
cclf___stg_beneficiary_demographics=df,
|
|
)
|
|
races = result.sort("person_id")["race"].to_list()
|
|
assert races == [
|
|
"unknown",
|
|
"white",
|
|
"black",
|
|
"other",
|
|
"asian",
|
|
"hispanic",
|
|
"native",
|
|
]
|
|
|
|
|
|
# ── _nullify_sentinel helper ────────────────────────────────
|
|
|
|
|
|
class TestNullifySentinel:
|
|
"""_nullify_sentinel replaces sentinel dates with null."""
|
|
|
|
def test_sentinel_1000_nullified(self) -> None:
|
|
df = nw.from_native(pl.DataFrame({"dt": ["1000-01-01", "2023-06-15"]}))
|
|
result = nw.to_native(df.select(_nullify_sentinel("dt")))
|
|
assert result["dt"].to_list() == [None, "2023-06-15"]
|
|
|
|
def test_sentinel_9999_nullified(self) -> None:
|
|
df = nw.from_native(pl.DataFrame({"dt": ["9999-12-31", "2023-06-15"]}))
|
|
result = nw.to_native(df.select(_nullify_sentinel("dt")))
|
|
assert result["dt"].to_list() == [None, "2023-06-15"]
|
|
|
|
def test_normal_dates_unchanged(self) -> None:
|
|
df = nw.from_native(pl.DataFrame({"dt": ["2023-01-01", "2024-12-31"]}))
|
|
result = nw.to_native(df.select(_nullify_sentinel("dt")))
|
|
assert result["dt"].to_list() == ["2023-01-01", "2024-12-31"]
|
|
|
|
|
|
# ── _icd_indicator helper ───────────────────────────────────
|
|
|
|
|
|
class TestIcdIndicator:
|
|
"""_icd_indicator maps ICD version codes to standard names."""
|
|
|
|
def test_icd10(self) -> None:
|
|
df = nw.from_native(pl.DataFrame({"dgns_prcdr_icd_ind": ["0"]}))
|
|
result = nw.to_native(df.select(_icd_indicator()))
|
|
assert result["diagnosis_code_type"].to_list() == ["icd-10-cm"]
|
|
|
|
def test_icd9(self) -> None:
|
|
df = nw.from_native(pl.DataFrame({"dgns_prcdr_icd_ind": ["9"]}))
|
|
result = nw.to_native(df.select(_icd_indicator()))
|
|
assert result["diagnosis_code_type"].to_list() == ["icd-9-cm"]
|
|
|
|
def test_unknown_yields_null(self) -> None:
|
|
df = nw.from_native(pl.DataFrame({"dgns_prcdr_icd_ind": ["U"]}))
|
|
result = nw.to_native(df.select(_icd_indicator()))
|
|
assert result["diagnosis_code_type"].to_list() == [None]
|
|
|
|
|
|
# ── stg_revenue_center (CCLF2) ──────────────────────────────
|
|
|
|
|
|
class TestStgRevenueCenter:
|
|
"""CCLF2 staging: MBI join."""
|
|
|
|
@pytest.fixture
|
|
def cclf2_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"bene_mbi_id": ["MBI-OLD", "MBI-KEEP"],
|
|
"cur_clm_uniq_id": ["C1", "C2"],
|
|
"clm_line_num": ["1", "2"],
|
|
}
|
|
)
|
|
|
|
def test_mbi_resolution(
|
|
self,
|
|
cclf2_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_revenue_center(
|
|
cclf__cclf2=cclf2_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
mbis = result.sort("cur_clm_uniq_id")["current_bene_mbi_id"].to_list()
|
|
assert mbis[0] == "MBI-NEW"
|
|
assert mbis[1] == "MBI-KEEP"
|
|
|
|
def test_row_count_preserved(
|
|
self,
|
|
cclf2_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_revenue_center(
|
|
cclf__cclf2=cclf2_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
assert result.shape[0] == cclf2_df.shape[0]
|
|
|
|
|
|
# ── int_diagnosis_pivot (CCLF4) ─────────────────────────────
|
|
|
|
|
|
class TestIntDiagnosisPivot:
|
|
"""Pivot CCLF4 from long to wide (25 dx slots)."""
|
|
|
|
@pytest.fixture
|
|
def cclf4_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["C1", "C1", "C1"],
|
|
"bene_mbi_id": ["MBI-A", "MBI-A", "MBI-A"],
|
|
"dgns_prcdr_icd_ind": ["0", "0", "0"],
|
|
"clm_val_sqnc_num": ["1", "2", "3"],
|
|
"clm_dgns_cd": ["J18.9", "E11.65", "I10"],
|
|
"clm_poa_ind": ["Y", "N", "Y"],
|
|
}
|
|
)
|
|
|
|
def test_pivot_creates_wide_columns(self, cclf4_df: pl.DataFrame) -> None:
|
|
result = int_diagnosis_pivot(cclf__cclf4=cclf4_df)
|
|
assert "diagnosis_code_1" in result.columns
|
|
assert "diagnosis_poa_1" in result.columns
|
|
assert "diagnosis_code_3" in result.columns
|
|
|
|
def test_pivot_values(self, cclf4_df: pl.DataFrame) -> None:
|
|
result = int_diagnosis_pivot(cclf__cclf4=cclf4_df)
|
|
assert result["diagnosis_code_1"].to_list() == ["J18.9"]
|
|
assert result["diagnosis_code_2"].to_list() == ["E11.65"]
|
|
assert result["diagnosis_poa_3"].to_list() == ["Y"]
|
|
|
|
def test_single_row_output(self, cclf4_df: pl.DataFrame) -> None:
|
|
result = int_diagnosis_pivot(cclf__cclf4=cclf4_df)
|
|
assert result.shape[0] == 1
|
|
|
|
def test_empty_sequence_filtered(self) -> None:
|
|
df = pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["C1"],
|
|
"bene_mbi_id": ["MBI-A"],
|
|
"dgns_prcdr_icd_ind": ["0"],
|
|
"clm_val_sqnc_num": [" "],
|
|
"clm_dgns_cd": ["J18.9"],
|
|
"clm_poa_ind": ["Y"],
|
|
}
|
|
)
|
|
result = int_diagnosis_pivot(cclf__cclf4=df)
|
|
# Blank sequence is stripped and filtered out
|
|
assert result.shape[0] == 0
|
|
|
|
|
|
# ── int_procedure_pivot (CCLF3) ─────────────────────────────
|
|
|
|
|
|
class TestIntProcedurePivot:
|
|
"""Pivot CCLF3 from long to wide (25 px slots)."""
|
|
|
|
@pytest.fixture
|
|
def cclf3_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["C1", "C1"],
|
|
"bene_mbi_id": ["MBI-A", "MBI-A"],
|
|
"dgns_prcdr_icd_ind": ["0", "0"],
|
|
"clm_val_sqnc_num": ["1", "2"],
|
|
"clm_prcdr_cd": ["02HV33Z", "0BJ08ZZ"],
|
|
"clm_prcdr_prfrm_dt": [
|
|
"2023-01-05",
|
|
"2023-01-06",
|
|
],
|
|
}
|
|
)
|
|
|
|
def test_pivot_creates_wide_columns(self, cclf3_df: pl.DataFrame) -> None:
|
|
result = int_procedure_pivot(cclf__cclf3=cclf3_df)
|
|
assert "procedure_code_1" in result.columns
|
|
assert "procedure_date_1" in result.columns
|
|
assert "procedure_code_2" in result.columns
|
|
|
|
def test_pivot_values(self, cclf3_df: pl.DataFrame) -> None:
|
|
result = int_procedure_pivot(cclf__cclf3=cclf3_df)
|
|
assert result["procedure_code_1"].to_list() == ["02HV33Z"]
|
|
assert result["procedure_code_2"].to_list() == ["0BJ08ZZ"]
|
|
|
|
def test_single_row_output(self, cclf3_df: pl.DataFrame) -> None:
|
|
result = int_procedure_pivot(cclf__cclf3=cclf3_df)
|
|
assert result.shape[0] == 1
|
|
|
|
|
|
# ── stg_dme_claim (CCLF6) ───────────────────────────────────
|
|
|
|
|
|
class TestStgDmeClaim:
|
|
"""CCLF6 staging: MBI join + cancellation negation."""
|
|
|
|
@pytest.fixture
|
|
def cclf6_df(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"bene_mbi_id": ["MBI-OLD", "MBI-KEEP"],
|
|
"clm_adjsmt_type_cd": ["1", "0"],
|
|
"clm_line_cvrd_pd_amt": [50.0, 75.0],
|
|
"clm_line_alowd_chrg_amt": [80.0, 120.0],
|
|
"cur_clm_uniq_id": ["D1", "D2"],
|
|
"clm_blg_prvdr_npi_num": ["NPI1", "NPI2"],
|
|
"clm_from_dt": ["2023-01-01", "2023-02-01"],
|
|
"clm_thru_dt": ["2023-01-10", "2023-02-10"],
|
|
}
|
|
)
|
|
|
|
def test_mbi_resolution(
|
|
self,
|
|
cclf6_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_dme_claim(
|
|
cclf__cclf6=cclf6_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
mbis = result.sort("cur_clm_uniq_id")["current_bene_mbi_id"].to_list()
|
|
assert mbis[0] == "MBI-NEW"
|
|
assert mbis[1] == "MBI-KEEP"
|
|
|
|
def test_cancelled_amounts_negated(
|
|
self,
|
|
cclf6_df: pl.DataFrame,
|
|
staged_xref: pl.DataFrame,
|
|
) -> None:
|
|
result = stg_dme_claim(
|
|
cclf__cclf6=cclf6_df,
|
|
cclf___stg_beneficiary_xref=staged_xref,
|
|
)
|
|
cancelled = result.filter(pl.col("clm_adjsmt_type_cd") == "1")
|
|
assert cancelled["clm_line_cvrd_pd_amt"].to_list() == [-50.0]
|
|
assert cancelled["clm_line_alowd_chrg_amt"].to_list() == [-80.0]
|
|
|
|
|
|
# ── int_dme_claim_adr ───────────────────────────────────────
|
|
|
|
|
|
class TestIntDmeClaimAdr:
|
|
"""ADR dedup for CCLF6."""
|
|
|
|
@pytest.fixture
|
|
def staged_cclf6(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"clm_blg_prvdr_npi_num": ["NPI1"] * 3,
|
|
"clm_from_dt": ["2023-01-01"] * 3,
|
|
"clm_thru_dt": ["2023-01-10"] * 3,
|
|
"current_bene_mbi_id": ["MBI-A"] * 3,
|
|
"cur_clm_uniq_id": ["D10", "D11", "D12"],
|
|
"clm_adjsmt_type_cd": ["0", "1", "2"],
|
|
"clm_line_cvrd_pd_amt": [50.0, -50.0, 55.0],
|
|
}
|
|
)
|
|
|
|
def test_keeps_latest_non_cancelled(self, staged_cclf6: pl.DataFrame) -> None:
|
|
result = int_dme_claim_adr(
|
|
cclf___stg_dme_claim=staged_cclf6,
|
|
)
|
|
assert result.shape[0] == 1
|
|
assert result["cur_clm_uniq_id"].to_list()[0] == "D12"
|
|
|
|
def test_drops_rn_column(self, staged_cclf6: pl.DataFrame) -> None:
|
|
result = int_dme_claim_adr(
|
|
cclf___stg_dme_claim=staged_cclf6,
|
|
)
|
|
assert "_rn" not in result.columns
|
|
|
|
|
|
# ── int_dme_medical_claim ────────────────────────────────────
|
|
|
|
|
|
class TestIntDmeMedicalClaim:
|
|
"""CCLF6 -> medical_claim schema (professional/DME)."""
|
|
|
|
@pytest.fixture
|
|
def adr_cclf6(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["D1"],
|
|
"clm_line_num": ["1"],
|
|
"current_bene_mbi_id": ["MBI-A"],
|
|
"clm_from_dt": ["2023-01-01"],
|
|
"clm_thru_dt": ["2023-01-10"],
|
|
"clm_line_from_dt": ["2023-01-01"],
|
|
"clm_line_thru_dt": ["2023-01-10"],
|
|
"clm_pos_cd": ["11"],
|
|
"clm_line_hcpcs_cd": ["E0601"],
|
|
"ordrg_prvdr_npi_num": ["NPI-ORD"],
|
|
"clm_blg_prvdr_npi_num": ["NPI-BLG"],
|
|
"clm_line_cvrd_pd_amt": [100.0],
|
|
"clm_line_alowd_chrg_amt": [150.0],
|
|
}
|
|
)
|
|
|
|
def test_claim_type_professional(self, adr_cclf6: pl.DataFrame) -> None:
|
|
result = int_dme_medical_claim(
|
|
cclf___int_dme_claim_adr=adr_cclf6,
|
|
)
|
|
assert result["claim_type"].to_list() == ["professional"]
|
|
|
|
def test_column_mapping(self, adr_cclf6: pl.DataFrame) -> None:
|
|
result = int_dme_medical_claim(
|
|
cclf___int_dme_claim_adr=adr_cclf6,
|
|
)
|
|
assert result["claim_id"].to_list() == ["D1"]
|
|
assert result["person_id"].to_list() == ["MBI-A"]
|
|
assert result["rendering_npi"].to_list() == ["NPI-ORD"]
|
|
assert result["billing_npi"].to_list() == ["NPI-BLG"]
|
|
assert result["paid_amount"].to_list() == [100.0]
|
|
assert result["allowed_amount"].to_list() == [150.0]
|
|
|
|
def test_null_dx_px_columns(self, adr_cclf6: pl.DataFrame) -> None:
|
|
result = int_dme_medical_claim(
|
|
cclf___int_dme_claim_adr=adr_cclf6,
|
|
)
|
|
assert result["diagnosis_code_1"].to_list() == [None]
|
|
assert result["procedure_code_1"].to_list() == [None]
|
|
assert result["diagnosis_code_type"].to_list() == [None]
|
|
|
|
def test_data_source(self, adr_cclf6: pl.DataFrame) -> None:
|
|
result = int_dme_medical_claim(
|
|
cclf___int_dme_claim_adr=adr_cclf6,
|
|
)
|
|
assert result["data_source"].to_list() == ["medicare cclf"]
|
|
assert result["in_network_flag"].to_list() == [1]
|
|
|
|
|
|
# ── int_physician_medical_claim ─────────────────────────────
|
|
|
|
|
|
class TestIntPhysicianMedicalClaim:
|
|
"""CCLF5 -> medical_claim schema (professional)."""
|
|
|
|
@pytest.fixture
|
|
def adr_cclf5(self) -> pl.DataFrame:
|
|
dx_cols = {
|
|
f"clm_dgns_{i}_cd": ["J18.9"] if i == 1 else [None] for i in range(1, 13)
|
|
}
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["C10"],
|
|
"clm_line_num": ["1"],
|
|
"current_bene_mbi_id": ["MBI-A"],
|
|
"clm_from_dt": ["2023-03-01"],
|
|
"clm_thru_dt": ["2023-03-05"],
|
|
"clm_line_from_dt": ["2023-03-01"],
|
|
"clm_line_thru_dt": ["2023-03-05"],
|
|
"clm_pos_cd": ["11"],
|
|
"clm_line_hcpcs_cd": ["99213"],
|
|
"hcpcs_1_mdfr_cd": ["25"],
|
|
"hcpcs_2_mdfr_cd": [None],
|
|
"hcpcs_3_mdfr_cd": [None],
|
|
"hcpcs_4_mdfr_cd": [None],
|
|
"hcpcs_5_mdfr_cd": [None],
|
|
"rndrg_prvdr_npi_num": ["NPI-R"],
|
|
"clm_rndrg_prvdr_tax_num": ["TIN-R"],
|
|
"clm_line_cvrd_pd_amt": [80.0],
|
|
"clm_line_alowd_chrg_amt": [120.0],
|
|
"clm_line_srvc_unit_qty": ["1"],
|
|
"dgns_prcdr_icd_ind": ["0"],
|
|
**dx_cols,
|
|
}
|
|
)
|
|
|
|
def test_claim_type_professional(self, adr_cclf5: pl.DataFrame) -> None:
|
|
result = int_physician_medical_claim(
|
|
cclf___int_physician_claim_adr=adr_cclf5,
|
|
)
|
|
assert result["claim_type"].to_list() == ["professional"]
|
|
|
|
def test_column_mapping(self, adr_cclf5: pl.DataFrame) -> None:
|
|
result = int_physician_medical_claim(
|
|
cclf___int_physician_claim_adr=adr_cclf5,
|
|
)
|
|
assert result["claim_id"].to_list() == ["C10"]
|
|
assert result["person_id"].to_list() == ["MBI-A"]
|
|
assert result["rendering_npi"].to_list() == ["NPI-R"]
|
|
assert result["rendering_tin"].to_list() == ["TIN-R"]
|
|
assert result["paid_amount"].to_list() == [80.0]
|
|
assert result["allowed_amount"].to_list() == [120.0]
|
|
|
|
def test_diagnosis_code_mapping(self, adr_cclf5: pl.DataFrame) -> None:
|
|
result = int_physician_medical_claim(
|
|
cclf___int_physician_claim_adr=adr_cclf5,
|
|
)
|
|
assert result["diagnosis_code_1"].to_list() == ["J18.9"]
|
|
assert result["diagnosis_code_type"].to_list() == ["icd-10-cm"]
|
|
# Codes 13-25 should be null (CCLF5 only has 12 inline)
|
|
assert result["diagnosis_code_13"].to_list() == [None]
|
|
assert result["diagnosis_code_25"].to_list() == [None]
|
|
|
|
def test_null_institutional_fields(self, adr_cclf5: pl.DataFrame) -> None:
|
|
result = int_physician_medical_claim(
|
|
cclf___int_physician_claim_adr=adr_cclf5,
|
|
)
|
|
assert result["admission_date"].to_list() == [None]
|
|
assert result["discharge_date"].to_list() == [None]
|
|
assert result["bill_type_code"].to_list() == [None]
|
|
assert result["drg_code"].to_list() == [None]
|
|
assert result["procedure_code_type"].to_list() == [None]
|
|
|
|
def test_data_source(self, adr_cclf5: pl.DataFrame) -> None:
|
|
result = int_physician_medical_claim(
|
|
cclf___int_physician_claim_adr=adr_cclf5,
|
|
)
|
|
assert result["data_source"].to_list() == ["medicare cclf"]
|
|
assert result["in_network_flag"].to_list() == [1]
|
|
|
|
|
|
# ── int_institutional_medical_claim ─────────────────────────
|
|
|
|
|
|
class TestIntInstitutionalMedicalClaim:
|
|
"""CCLF1+2+3+4 -> medical_claim schema (institutional)."""
|
|
|
|
@pytest.fixture
|
|
def header_adr(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["C1"],
|
|
"current_bene_mbi_id": ["MBI-A"],
|
|
"bene_mbi_id": ["MBI-A"],
|
|
"prvdr_oscar_num": ["H1"],
|
|
"clm_from_dt": ["2023-01-01"],
|
|
"clm_thru_dt": ["2023-01-10"],
|
|
"clm_adjsmt_type_cd": ["0"],
|
|
"clm_pmt_amt": [1000.0],
|
|
"clm_mdcr_instnl_tot_chrg_amt": [5000.0],
|
|
"dgns_prcdr_icd_ind": ["0"],
|
|
"clm_admsn_src_cd": ["1"],
|
|
"clm_admsn_type_cd": ["3"],
|
|
"bene_ptnt_stus_cd": ["01"],
|
|
"clm_bill_fac_type_cd": ["1"],
|
|
"clm_bill_clsfctn_cd": ["1"],
|
|
"clm_bill_freq_cd": ["1"],
|
|
"dgns_drg_cd": ["MS470"],
|
|
"oprtg_prvdr_npi_num": ["NPI-OP"],
|
|
"clm_blg_prvdr_npi_num": ["NPI-BLG"],
|
|
"fac_prvdr_npi_num": ["NPI-FAC"],
|
|
}
|
|
)
|
|
|
|
@pytest.fixture
|
|
def revenue_center(self) -> pl.DataFrame:
|
|
return pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["C1"],
|
|
"current_bene_mbi_id": ["MBI-A"],
|
|
"bene_mbi_id": ["MBI-A"],
|
|
"clm_line_num": ["1"],
|
|
"clm_line_from_dt": ["2023-01-01"],
|
|
"clm_line_thru_dt": ["2023-01-10"],
|
|
"clm_line_prod_rev_ctr_cd": ["0120"],
|
|
"clm_line_srvc_unit_qty": ["5"],
|
|
"clm_line_hcpcs_cd": ["99213"],
|
|
"hcpcs_1_mdfr_cd": ["25"],
|
|
"hcpcs_2_mdfr_cd": [None],
|
|
"hcpcs_3_mdfr_cd": [None],
|
|
"hcpcs_4_mdfr_cd": [None],
|
|
"hcpcs_5_mdfr_cd": [None],
|
|
"clm_line_cvrd_pd_amt": [800.0],
|
|
}
|
|
)
|
|
|
|
@pytest.fixture
|
|
def dx_pivot(self) -> pl.DataFrame:
|
|
data: dict = {
|
|
"cur_clm_uniq_id": ["C1"],
|
|
"bene_mbi_id": ["MBI-A"],
|
|
"dgns_prcdr_icd_ind": ["0"],
|
|
}
|
|
for i in range(1, 26):
|
|
data[f"diagnosis_code_{i}"] = ["J18.9"] if i == 1 else [None]
|
|
data[f"diagnosis_poa_{i}"] = ["Y"] if i == 1 else [None]
|
|
return pl.DataFrame(data)
|
|
|
|
@pytest.fixture
|
|
def px_pivot(self) -> pl.DataFrame:
|
|
data: dict = {
|
|
"cur_clm_uniq_id": ["C1"],
|
|
"bene_mbi_id": ["MBI-A"],
|
|
"dgns_prcdr_icd_ind": ["0"],
|
|
}
|
|
for i in range(1, 26):
|
|
data[f"procedure_code_{i}"] = ["02HV33Z"] if i == 1 else [None]
|
|
data[f"procedure_date_{i}"] = ["2023-01-05"] if i == 1 else [None]
|
|
return pl.DataFrame(data)
|
|
|
|
def test_claim_type_institutional(
|
|
self,
|
|
header_adr: pl.DataFrame,
|
|
revenue_center: pl.DataFrame,
|
|
dx_pivot: pl.DataFrame,
|
|
px_pivot: pl.DataFrame,
|
|
) -> None:
|
|
result = int_institutional_medical_claim(
|
|
cclf___int_institutional_header_adr=header_adr,
|
|
cclf___stg_revenue_center=revenue_center,
|
|
cclf___int_diagnosis_pivot=dx_pivot,
|
|
cclf___int_procedure_pivot=px_pivot,
|
|
)
|
|
assert result["claim_type"].to_list() == ["institutional"]
|
|
|
|
def test_column_mapping(
|
|
self,
|
|
header_adr: pl.DataFrame,
|
|
revenue_center: pl.DataFrame,
|
|
dx_pivot: pl.DataFrame,
|
|
px_pivot: pl.DataFrame,
|
|
) -> None:
|
|
result = int_institutional_medical_claim(
|
|
cclf___int_institutional_header_adr=header_adr,
|
|
cclf___stg_revenue_center=revenue_center,
|
|
cclf___int_diagnosis_pivot=dx_pivot,
|
|
cclf___int_procedure_pivot=px_pivot,
|
|
)
|
|
assert result["claim_id"].to_list() == ["C1"]
|
|
assert result["person_id"].to_list() == ["MBI-A"]
|
|
assert result["payer"].to_list() == ["medicare"]
|
|
assert result["data_source"].to_list() == ["medicare cclf"]
|
|
|
|
def test_bill_type_concatenation(
|
|
self,
|
|
header_adr: pl.DataFrame,
|
|
revenue_center: pl.DataFrame,
|
|
dx_pivot: pl.DataFrame,
|
|
px_pivot: pl.DataFrame,
|
|
) -> None:
|
|
result = int_institutional_medical_claim(
|
|
cclf___int_institutional_header_adr=header_adr,
|
|
cclf___stg_revenue_center=revenue_center,
|
|
cclf___int_diagnosis_pivot=dx_pivot,
|
|
cclf___int_procedure_pivot=px_pivot,
|
|
)
|
|
assert result["bill_type_code"].to_list() == ["111"]
|
|
|
|
def test_drg_extraction(
|
|
self,
|
|
header_adr: pl.DataFrame,
|
|
revenue_center: pl.DataFrame,
|
|
dx_pivot: pl.DataFrame,
|
|
px_pivot: pl.DataFrame,
|
|
) -> None:
|
|
result = int_institutional_medical_claim(
|
|
cclf___int_institutional_header_adr=header_adr,
|
|
cclf___stg_revenue_center=revenue_center,
|
|
cclf___int_diagnosis_pivot=dx_pivot,
|
|
cclf___int_procedure_pivot=px_pivot,
|
|
)
|
|
# rightmost 3 chars of "MS470" => "470"
|
|
assert result["drg_code"].to_list() == ["470"]
|
|
assert result["drg_code_type"].to_list() == ["ms-drg"]
|
|
|
|
def test_diagnosis_code_mapping(
|
|
self,
|
|
header_adr: pl.DataFrame,
|
|
revenue_center: pl.DataFrame,
|
|
dx_pivot: pl.DataFrame,
|
|
px_pivot: pl.DataFrame,
|
|
) -> None:
|
|
result = int_institutional_medical_claim(
|
|
cclf___int_institutional_header_adr=header_adr,
|
|
cclf___stg_revenue_center=revenue_center,
|
|
cclf___int_diagnosis_pivot=dx_pivot,
|
|
cclf___int_procedure_pivot=px_pivot,
|
|
)
|
|
assert result["diagnosis_code_1"].to_list() == ["J18.9"]
|
|
assert result["diagnosis_code_type"].to_list() == ["icd-10-cm"]
|
|
|
|
def test_procedure_code_mapping(
|
|
self,
|
|
header_adr: pl.DataFrame,
|
|
revenue_center: pl.DataFrame,
|
|
dx_pivot: pl.DataFrame,
|
|
px_pivot: pl.DataFrame,
|
|
) -> None:
|
|
result = int_institutional_medical_claim(
|
|
cclf___int_institutional_header_adr=header_adr,
|
|
cclf___stg_revenue_center=revenue_center,
|
|
cclf___int_diagnosis_pivot=dx_pivot,
|
|
cclf___int_procedure_pivot=px_pivot,
|
|
)
|
|
assert result["procedure_code_1"].to_list() == ["02HV33Z"]
|
|
assert result["procedure_code_type"].to_list() == ["icd-10-pcs"]
|
|
|
|
def test_sentinel_date_nullified(
|
|
self,
|
|
revenue_center: pl.DataFrame,
|
|
dx_pivot: pl.DataFrame,
|
|
px_pivot: pl.DataFrame,
|
|
) -> None:
|
|
"""Sentinel clm_from_dt should be nullified."""
|
|
hdr = pl.DataFrame(
|
|
{
|
|
"cur_clm_uniq_id": ["C1"],
|
|
"current_bene_mbi_id": ["MBI-A"],
|
|
"bene_mbi_id": ["MBI-A"],
|
|
"prvdr_oscar_num": ["H1"],
|
|
"clm_from_dt": ["1000-01-01"],
|
|
"clm_thru_dt": ["2023-01-10"],
|
|
"clm_adjsmt_type_cd": ["0"],
|
|
"clm_pmt_amt": [1000.0],
|
|
"clm_mdcr_instnl_tot_chrg_amt": [5000.0],
|
|
"dgns_prcdr_icd_ind": ["0"],
|
|
"clm_admsn_src_cd": ["1"],
|
|
"clm_admsn_type_cd": ["3"],
|
|
"bene_ptnt_stus_cd": ["01"],
|
|
"clm_bill_fac_type_cd": ["1"],
|
|
"clm_bill_clsfctn_cd": ["1"],
|
|
"clm_bill_freq_cd": ["1"],
|
|
"dgns_drg_cd": ["MS470"],
|
|
"oprtg_prvdr_npi_num": ["NPI-OP"],
|
|
"clm_blg_prvdr_npi_num": ["NPI-BLG"],
|
|
"fac_prvdr_npi_num": ["NPI-FAC"],
|
|
}
|
|
)
|
|
result = int_institutional_medical_claim(
|
|
cclf___int_institutional_header_adr=hdr,
|
|
cclf___stg_revenue_center=revenue_center,
|
|
cclf___int_diagnosis_pivot=dx_pivot,
|
|
cclf___int_procedure_pivot=px_pivot,
|
|
)
|
|
# Sentinel clm_from_dt should be nullified in claim_start_date
|
|
assert result["claim_start_date"].to_list() == [None]
|
|
assert result["admission_date"].to_list() == [None]
|
|
|
|
|
|
# ── medical_claim (final union) ─────────────────────────────
|
|
|
|
|
|
class TestMedicalClaim:
|
|
"""Union of institutional + physician + DME."""
|
|
|
|
def _make_medical_claim_row(self, claim_id: str, claim_type: str) -> pl.DataFrame:
|
|
"""Build a minimal medical_claim row."""
|
|
data: dict = {
|
|
"claim_id": [claim_id],
|
|
"claim_line_number": [1],
|
|
"claim_type": [claim_type],
|
|
"person_id": ["MBI-A"],
|
|
"member_id": ["MBI-A"],
|
|
"payer": ["medicare"],
|
|
"plan": ["medicare"],
|
|
"claim_start_date": ["2023-01-01"],
|
|
"claim_end_date": ["2023-01-10"],
|
|
"claim_line_start_date": ["2023-01-01"],
|
|
"claim_line_end_date": ["2023-01-10"],
|
|
"admission_date": [None],
|
|
"discharge_date": [None],
|
|
"admit_source_code": [None],
|
|
"admit_type_code": [None],
|
|
"discharge_disposition_code": [None],
|
|
"place_of_service_code": [None],
|
|
"bill_type_code": [None],
|
|
"drg_code_type": [None],
|
|
"drg_code": [None],
|
|
"revenue_center_code": [None],
|
|
"service_unit_quantity": [None],
|
|
"hcpcs_code": ["99213"],
|
|
"hcpcs_modifier_1": [None],
|
|
"hcpcs_modifier_2": [None],
|
|
"hcpcs_modifier_3": [None],
|
|
"hcpcs_modifier_4": [None],
|
|
"hcpcs_modifier_5": [None],
|
|
"rendering_npi": [None],
|
|
"rendering_tin": [None],
|
|
"billing_npi": [None],
|
|
"billing_tin": [None],
|
|
"facility_npi": [None],
|
|
"paid_date": [None],
|
|
"paid_amount": [100.0],
|
|
"allowed_amount": [None],
|
|
"charge_amount": [None],
|
|
"coinsurance_amount": [None],
|
|
"copayment_amount": [None],
|
|
"deductible_amount": [None],
|
|
"total_cost_amount": [None],
|
|
"diagnosis_code_type": [None],
|
|
}
|
|
for i in range(1, 26):
|
|
data[f"diagnosis_code_{i}"] = [None]
|
|
data[f"diagnosis_poa_{i}"] = [None]
|
|
data["procedure_code_type"] = [None]
|
|
for i in range(1, 26):
|
|
data[f"procedure_code_{i}"] = [None]
|
|
data[f"procedure_date_{i}"] = [None]
|
|
data["in_network_flag"] = [1]
|
|
data["data_source"] = ["medicare cclf"]
|
|
data["file_name"] = [None]
|
|
data["file_date"] = [None]
|
|
data["ingest_datetime"] = [None]
|
|
return pl.DataFrame(data)
|
|
|
|
def test_union_row_count(self) -> None:
|
|
inst = self._make_medical_claim_row("I1", "institutional")
|
|
phys = self._make_medical_claim_row("P1", "professional")
|
|
dme = self._make_medical_claim_row("D1", "professional")
|
|
result = medical_claim(
|
|
cclf___int_institutional_medical_claim=inst,
|
|
cclf___int_physician_medical_claim=phys,
|
|
cclf___int_dme_medical_claim=dme,
|
|
)
|
|
assert result.shape[0] == 3
|
|
|
|
def test_union_claim_types(self) -> None:
|
|
inst = self._make_medical_claim_row("I1", "institutional")
|
|
phys = self._make_medical_claim_row("P1", "professional")
|
|
dme = self._make_medical_claim_row("D1", "professional")
|
|
result = medical_claim(
|
|
cclf___int_institutional_medical_claim=inst,
|
|
cclf___int_physician_medical_claim=phys,
|
|
cclf___int_dme_medical_claim=dme,
|
|
)
|
|
types = sorted(result["claim_type"].unique().to_list())
|
|
assert types == ["institutional", "professional"]
|
|
|
|
def test_union_claim_ids(self) -> None:
|
|
inst = self._make_medical_claim_row("I1", "institutional")
|
|
phys = self._make_medical_claim_row("P1", "professional")
|
|
dme = self._make_medical_claim_row("D1", "professional")
|
|
result = medical_claim(
|
|
cclf___int_institutional_medical_claim=inst,
|
|
cclf___int_physician_medical_claim=phys,
|
|
cclf___int_dme_medical_claim=dme,
|
|
)
|
|
ids = sorted(result["claim_id"].to_list())
|
|
assert ids == ["D1", "I1", "P1"]
|