r""" conditions/medicare_billing_screening.py — document #14: on a Medicare claim the depression screening codes G8510/G8431 are not billed (unchecked, Billed Fee zeroed), and the depression-pointer process (#6) does not run. Only the screening codes are touched; every other CPT line is left as it is. python tests\test_conditions_medicare_billing_screening.py Uses hcfa_claim.html: 99213 (row 0), J7298 (row 1), and G8510 (row 2, unchecked at 65.00 in the fixture — checked here where a case needs it). """ import sys import pathlib import inspect ROOT = pathlib.Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "src")) FIXTURE = pathlib.Path(__file__).resolve().parent / "fixtures" / "hcfa_claim.html" from ecw_bot.conditions import medicare_billing_screening as mbs # noqa: E402 from ecw_bot.conditions import depression_dx_pointer # noqa: E402 from ecw_bot.conditions.base import run_all # noqa: E402 from ecw_bot.pages import claim_form # noqa: E402 from ecw_bot.selectors import claim_form as sel # noqa: E402 CASES = [] MEDICARE = [{"Name": "HCFA Medicare"}] MEDICARE_ADVANTAGE = [{"Name": "AARP Medicare Advantage"}] MEDICAID = [{"Name": "APM2 Medicaid"}] def case(fn): CASES.append(fn) return fn def _check_row(page, index): page.evaluate( """(i) => { const rows = document.querySelectorAll('tr[id^="CPTROW_"]'); const box = rows[i].querySelector('[ng-click*="updateBillToIns("]'); box.checked = true; box.setAttribute('checked', ''); }""", index) def _row_state(page, index): row = page.locator(sel.SEL_CPT_ROWS).nth(index) return (row.locator(sel.SEL_CPT_ASSIGN_TO_PATIENT).first.is_checked(), row.locator(sel.SEL_CPT_BILLED_FEE).first.input_value()) def _remove_rows_except(page, keep_codes): page.evaluate( """(keep) => { for (const tr of document.querySelectorAll('tr[id^="CPTROW_"]')) { const c = tr.querySelector('[data-fieldname="claimCPTCode"]'); if (c && !keep.includes(c.value)) tr.remove(); } }""", keep_codes) # ── detect ─────────────────────────────────────────────────────────────────── @case def detect_true_for_medicare_with_g8510(): data = {"insurance": MEDICARE, "cpt": [{"code": "99213"}, {"code": "G8510"}]} assert mbs.detect("C1", data) is True @case def detect_true_for_medicare_with_g8431(): data = {"insurance": MEDICARE, "cpt": [{"code": "G8431"}]} assert mbs.detect("C1", data) is True @case def detect_false_for_a_medicare_advantage_plan(): # Ruling 2026-10-21: the dashboard's Commercial Ins, not Medicare. data = {"insurance": MEDICARE_ADVANTAGE, "cpt": [{"code": "G8510"}]} assert mbs.detect("C1", data) is False @case def detect_false_for_a_non_medicare_payer(): data = {"insurance": MEDICAID, "cpt": [{"code": "G8510"}]} assert mbs.detect("C1", data) is False @case def detect_false_for_an_unmapped_or_missing_payer(): assert mbs.detect("C1", {"insurance": [{"Name": "Nobody Knows"}], "cpt": [{"code": "G8510"}]}) is False assert mbs.detect("C1", {"cpt": [{"code": "G8510"}]}) is False @case def detect_false_for_medicare_without_screening_codes(): data = {"insurance": MEDICARE, "cpt": [{"code": "99213"}]} assert mbs.detect("C1", data) is False # ── the depression process (#6) stays off for Medicare ────────────────────── _DEPRESSION_ICD = [{"#": "2", "Code": "Z13.31"}] @case def depression_process_does_not_run_for_medicare(): data = {"insurance": MEDICARE, "icd": _DEPRESSION_ICD, "cpt": [{"code": "99213"}, {"code": "G8510"}]} assert depression_dx_pointer.detect("C1", data) is False @case def depression_process_still_runs_for_other_payers(): for ins in (MEDICAID, [{"Name": "Nobody Knows"}], []): data = {"insurance": ins, "icd": _DEPRESSION_ICD, "cpt": [{"code": "99213"}, {"code": "G8510"}]} assert depression_dx_pointer.detect("C1", data) is True, ins # ── apply ──────────────────────────────────────────────────────────────────── @case def apply_unchecks_and_zeroes_g8510_and_leaves_other_codes(page): page.goto(FIXTURE.as_uri()) _check_row(page, 2) before = [_row_state(page, i) for i in (0, 1)] data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} result = mbs.apply(page, "C1", data) assert result.changed is True assert result.review == "", result.review assert result.changes == [{"row": 2, "code": "G8510", "unchecked": True, "fee": {"before": "65.00", "after": "0.00"}}], \ result.changes assert _row_state(page, 2) == (False, "0.00") assert [_row_state(page, i) for i in (0, 1)] == before, \ "99213 and J7298 must be left exactly as they were" @case def apply_zeroes_an_already_unchecked_priced_g8510(page): page.goto(FIXTURE.as_uri()) data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} result = mbs.apply(page, "C1", data) assert result.changed is True assert result.changes == [{"row": 2, "code": "G8510", "fee": {"before": "65.00", "after": "0.00"}}], \ result.changes @case def apply_screening_only_zeroes_it_and_asks_for_provider_clarification(page): page.goto(FIXTURE.as_uri()) _remove_rows_except(page, ["G8510"]) _check_row(page, 0) data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} result = mbs.apply(page, "C1", data) assert result.changed is True assert _row_state(page, 0) == (False, "0.00") assert result.review == mbs.SCREENING_ONLY, result.review @case def apply_is_a_no_op_once_screening_is_already_excluded(page): page.goto(FIXTURE.as_uri()) page.evaluate("""() => { const rows = document.querySelectorAll('tr[id^="CPTROW_"]'); rows[2].querySelector('[data-fieldname="ClaimCPTBilledFee"]').value = '0.00'; }""") data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} result = mbs.apply(page, "C1", data) assert result.changed is False assert result.changes == [] def _set_row(page, index, *, checked=None, fee=None, drop_checkbox=False): page.evaluate( """(a) => { const tr = document.querySelectorAll('tr[id^="CPTROW_"]')[a.i]; const box = tr.querySelector('[ng-click*="updateBillToIns("]'); if (a.drop) box.remove(); else if (a.checked !== null) { box.checked = a.checked; if (a.checked) box.setAttribute('checked', ''); else box.removeAttribute('checked'); } if (a.fee !== null) tr.querySelector('[data-fieldname="ClaimCPTBilledFee"]').value = a.fee; }""", {"i": index, "checked": checked, "fee": fee, "drop": drop_checkbox}) @case def screening_only_is_judged_on_the_grid_after_the_other_conditions(page): """ Review finding 1 (2026-10-12): the read said 99213 was billed, but an earlier condition (zero_fee_uncheck, a dummy/J-code exclusion) has unchecked it since — once G8510 is gone too, nothing is billed. """ page.goto(FIXTURE.as_uri()) _remove_rows_except(page, ["99213", "G8510"]) _check_row(page, 1) data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} assert data["cpt"][0]["billed"] is True _set_row(page, 0, checked=False, fee="0.00") result = mbs.apply(page, "C1", data) assert result.changed is True assert result.review == mbs.SCREENING_ONLY, result.review @case def a_ub_line_with_no_checkbox_at_zero_is_not_billed(page): """UB: no Assign-To-Patient checkbox (billed None) at 0.00.""" page.goto(FIXTURE.as_uri()) _remove_rows_except(page, ["99213", "G8510"]) _check_row(page, 1) _set_row(page, 0, drop_checkbox=True, fee="0.00") data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} result = mbs.apply(page, "C1", data) assert result.review == mbs.SCREENING_ONLY, result.review @case def a_billed_line_left_on_the_grid_is_not_screening_only(page): page.goto(FIXTURE.as_uri()) _remove_rows_except(page, ["99213", "G8510"]) _check_row(page, 1) _set_row(page, 0, drop_checkbox=True, fee="210.00") data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} result = mbs.apply(page, "C1", data) assert result.changed is True and result.review == "", result.review @case def an_empty_live_grid_declines_instead_of_passing(page): """Review finding 2: the grid did not re-render after the tab click.""" page.goto(FIXTURE.as_uri()) _check_row(page, 2) data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} _remove_rows_except(page, []) result = mbs.apply(page, "C1", data) assert result.changed is False assert result.review == mbs.CPT_GRID_NOT_READ, result.review @case def summary_comment_says_fee_zeroed_when_no_checkbox_was_unchecked(): """ Review finding 3, operator 2026-10-12 (option A): on a UB form with no Assign-To-Patient checkbox, zeroing the fee is the fix — the comment must not claim "unchecked". """ fee_only = mbs.ConditionResult( condition_name=mbs.NAME, changed=True, changes=[{"row": 0, "code": "G8510", "fee": {"before": "65.00", "after": "0.00"}}]) text = mbs.summary_comment(fee_only) assert "fee zeroed" in text and "unchecked" not in text, text both = mbs.ConditionResult( condition_name=mbs.NAME, changed=True, changes=[{"row": 0, "code": "G8510", "unchecked": True, "fee": {"before": "65.00", "after": "0.00"}}]) text = mbs.summary_comment(both) assert "unchecked" in text and "fee zeroed" in text, text @case def describe_names_the_code_and_the_fee(page): page.goto(FIXTURE.as_uri()) _check_row(page, 2) data = {"insurance": MEDICARE, "cpt": claim_form.extract(page)["cpt"]} text = mbs.describe(mbs.apply(page, "C1", data)) assert "G8510" in text and "Medicare" in text, text assert "65.00" in text and "0.00" in text, text @case def run_all_on_medicare_runs_this_and_not_the_depression_process(page): """ Against the REAL registry: on a Medicare claim with Z13.31, only this condition fires — depression_dx_pointer would otherwise re-check the G8510 this one just excluded. """ page.goto(FIXTURE.as_uri()) _check_row(page, 2) data = claim_form.extract(page) data["insurance"] = MEDICARE data["icd"] = _DEPRESSION_ICD report = {} results = run_all(page, "C1", data, report=report) assert "depression_dx_pointer" not in report["fired"], report assert [r.condition_name for r in results] == ["medicare_billing_screening"], \ results assert _row_state(page, 2) == (False, "0.00") def main() -> int: if not FIXTURE.exists(): print(f" FAIL fixture missing: {FIXTURE}") return 1 try: from playwright.sync_api import sync_playwright except ImportError: print(" SKIP playwright is not installed") return 0 failures = 0 with sync_playwright() as pw: browser = pw.chromium.launch(headless=True) page = browser.new_page() for fn in CASES: name = fn.__name__.replace("_", " ") try: if len(inspect.signature(fn).parameters) == 0: fn() else: fn(page) print(f" ok {name}") except AssertionError as exc: print(f" FAIL {name}: {exc}") failures += 1 except Exception as exc: print(f" ERROR {name}: {type(exc).__name__}: {exc}") failures += 1 browser.close() print(f"\n{len(CASES) - failures}/{len(CASES)} passed") return 1 if failures else 0 if __name__ == "__main__": sys.exit(main())