r""" conditions/medicaid_pregnancy_th.py — document #23: a pregnancy visit on Medicaid (not RAE) gets the TH modifier on its E&M / primary line, in M1 (overwriting what M1 held — operator 2026-10-21); Z32.00-Z32.02 (pregnancy test) do not count; a Medicaid telehealth pregnancy visit gets TH instead of GT (telehealth #21). python tests\test_conditions_medicaid_pregnancy_th.py Uses hcfa_claim.html with injected rows (data-fieldname inputs, like test_conditions_bh_h_code_modifier.py). """ import io import sys import inspect import pathlib import contextlib 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 medicaid_pregnancy_th as cond # noqa: E402 from ecw_bot.conditions import telehealth # noqa: E402 from ecw_bot.conditions import CONDITIONS # noqa: E402 from ecw_bot.conditions.base import ConditionResult # noqa: E402 from ecw_bot.core import charge_summary as cs # noqa: E402 from ecw_bot.selectors import claim_form as sel # noqa: E402 CASES = [] MEDICAID = [{"Name": "APM2 Medicaid"}] RAE = [{"Name": "BH COLORADO ACCESS"}] COMMERCIAL = [{"Name": "AARP"}] def case(fn): CASES.append(fn) return fn def _data(ins=MEDICAID, icds=("O09.90",), lines=(("99214", ""),)): cpt = [{"code": c, "billed_fee": "100.00", "billed": True, "mod1": m1, "mod2": "", "mod3": "", "mod4": ""} for c, m1 in lines] return {"screen": "hcfa", "insurance": list(ins), "icd": [{"Code": i} for i in icds], "cpt": cpt} def _inject(page, code="99213", mods=("", "", "", ""), row_id="CPTROW_7"): page.evaluate( """(a) => { const tbody = document.querySelector( '#claimCPTCodesTable8888888888888 tbody'); const last = tbody.querySelector('tr:last-child'); const tr = document.createElement('tr'); tr.id = a.rowId; let html = '' + '' + ''; a.mods.forEach((m, i) => { html += ''; }); html += ''; tr.innerHTML = html; tbody.insertBefore(tr, last); }""", {"code": code, "mods": list(mods), "rowId": row_id}) def _mods_of(page, code): rows = page.locator(sel.SEL_CPT_ROWS) for i in range(rows.count()): row = rows.nth(i) c = row.locator(sel.SEL_CPT_CODE).first if c.count() and c.input_value().strip() == code: return [row.locator(s).first.input_value() for s in sel.SEL_CPT_MOD] return None def _apply(page, data): with contextlib.redirect_stdout(io.StringIO()): return cond.apply(page, "C1", data) # ── detect (no browser) ────────────────────────────────────────────────────── @case def a_pregnancy_icd_on_medicaid_fires(): for icd in ("O09.90", "O26.891", "Z34.81", "Z33.1", "Z3A.12", "Z36.89"): assert cond.detect("C1", _data(icds=("Z00.00", icd))), icd @case def pregnancy_test_icds_alone_do_not_fire(): assert not cond.detect("C1", _data(icds=("Z32.00",))) assert not cond.detect("C1", _data(icds=("Z32.01", "Z32.02", "R10.9"))) assert cond.detect("C1", _data(icds=("Z32.01", "O09.90"))) @case def medicaid_only_not_rae_or_others(): assert not cond.detect("C1", _data(ins=RAE)) assert not cond.detect("C1", _data(ins=COMMERCIAL)) assert not cond.detect("C1", _data(ins=[])) assert not cond.detect("C1", {}) @case def th_already_on_the_line_is_nothing(): data = _data() data["cpt"][0]["mod2"] = "th" assert not cond.detect("C1", data) @case def the_e_and_m_line_is_the_target_else_the_first_billed(): data = _data(lines=(("90471", ""), ("99214", ""), ("99213", ""))) assert cond.target_code(data) == "99214" data = _data(lines=(("59025", ""), ("81025", ""))) assert cond.target_code(data) == "59025" data = _data(lines=(("99213", ""),)) data["cpt"][0]["billed_fee"] = "0.00" assert cond.target_code(data) is None assert not cond.detect("C1", data) # ── apply (browser) ────────────────────────────────────────────────────────── @case def th_goes_in_an_empty_m1(page): page.goto(FIXTURE.as_uri()) _inject(page, "99214", ("", "", "", "")) result = _apply(page, _data()) assert isinstance(result, ConditionResult) and result.changed, result assert result.review == "", result.review assert _mods_of(page, "99214") == ["TH", "", "", ""] c = result.changes[0] assert c["code"] == "99214" and c["box"] == 1 and c["icds"] == ["O09.90"] assert "TH modifier added on 99214" in cond.summary_comment(result) assert "M1" in cond.describe(result) @case def m1_in_use_is_overwritten_with_th(page): page.goto(FIXTURE.as_uri()) _inject(page, "99214", ("25", "", "", "")) result = _apply(page, _data(lines=(("99214", "25"),))) assert _mods_of(page, "99214") == ["TH", "", "", ""] c = result.changes[0] assert c["box"] == 1 and c["before"] == "25" and result.review == "" assert "TH modifier added on 99214, replacing 25" in cond.summary_comment(result) assert "M1 25 -> TH" in cond.describe(result) @case def all_four_boxes_full_still_overwrites_m1_only(page): page.goto(FIXTURE.as_uri()) _inject(page, "99214", ("25", "59", "XU", "GA")) result = _apply(page, _data(lines=(("99214", "25"),))) assert result.changed is True and result.review == "", result assert _mods_of(page, "99214") == ["TH", "59", "XU", "GA"] @case def th_in_another_box_is_left_alone(page): page.goto(FIXTURE.as_uri()) _inject(page, "99214", ("25", "TH", "", "")) result = _apply(page, _data(lines=(("99214", "25"),))) assert result.changed is False and result.review == "", result assert _mods_of(page, "99214") == ["25", "TH", "", ""] @case def th_already_on_the_live_line_is_nothing(page): page.goto(FIXTURE.as_uri()) _inject(page, "99214", ("TH", "", "", "")) result = _apply(page, _data()) assert result.changed is False and result.review == "", result @case def a_line_missing_from_the_live_grid_is_review(page): page.goto(FIXTURE.as_uri()) result = _apply(page, _data(lines=(("99215", ""),))) assert result.changed is False and "could not be read" in result.review # ── telehealth #21: TH, not GT ─────────────────────────────────────────────── @case def telehealth_writes_th_not_gt_on_a_medicaid_pregnancy_visit(page): page.goto(FIXTURE.as_uri()) data = _data() data["progress_notes"] = {"opened": "tab", "text": "Session Setting (PoS): TeleHealth"} rows = page.locator(sel.SEL_CPT_ROWS) first = rows.nth(0).locator(sel.SEL_CPT_CODE).first.input_value().strip() with contextlib.redirect_stdout(io.StringIO()): result = telehealth.apply(page, "C1", data) assert result.changed, result assert result.changes[0]["modifier"] == "TH", result.changes assert _mods_of(page, first)[0] == "TH" @case def telehealth_keeps_gt_for_rae_and_for_no_pregnancy(page): for ins, icds in ((RAE, ("O09.90",)), (MEDICAID, ("Z32.01",))): page.goto(FIXTURE.as_uri()) data = _data(ins=ins, icds=icds) data["progress_notes"] = {"opened": "tab", "text": "Session Setting (PoS): TeleHealth"} with contextlib.redirect_stdout(io.StringIO()): result = telehealth.apply(page, "C1", data) assert result.changes[0]["modifier"] == "GT", (ins, icds) # ── registry and Charge Summary ────────────────────────────────────────────── @case def it_is_registered_after_telehealth_and_before_priced_line_check(): names = [m.NAME for m in CONDITIONS] assert names.index("telehealth") < names.index("medicaid_pregnancy_th") \ < names.index("priced_line_check"), names assert "medicaid_pregnancy_th" in cs.COMMENTS def main() -> int: from playwright.sync_api import sync_playwright 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())