Snapshot of the working project as of 2026-10-23 (local 2d4d4fc), one commit with no earlier history: the tracked files were de-identified first (synthetic claim ids and patient data only; see Context.md section 7). Credentials, run logs, screenshots, claim reports and client workbooks are gitignored and not included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
215 lines
8.2 KiB
Python
215 lines
8.2 KiB
Python
r"""
|
|
conditions/medicaid_uncheck_cpts.py — document #43 (15851, 15852) and #44
|
|
(73521): never billed to Medicaid, so on a Medicaid claim each is
|
|
unchecked and its Billed Fee zeroed (operator, 2026-10-13). Any other
|
|
payer — Medicare, Commercial, a RAE payer, an unmapped or unread one —
|
|
keeps them.
|
|
|
|
python tests\test_conditions_medicaid_uncheck_cpts.py
|
|
|
|
Uses hcfa_claim.html like the dummy codes tests: none of the three codes
|
|
has a row there, so `_inject_cpt_row()` adds one per case.
|
|
"""
|
|
|
|
import io
|
|
import sys
|
|
import pathlib
|
|
import inspect
|
|
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_uncheck_cpts as cond # noqa: E402
|
|
from ecw_bot.conditions import CONDITIONS # noqa: E402
|
|
from ecw_bot.conditions.base import ConditionResult, run_all # 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 = []
|
|
|
|
|
|
def case(fn):
|
|
CASES.append(fn)
|
|
return fn
|
|
|
|
|
|
def _claim(payer, *codes):
|
|
return {"insurance": [{"Name": payer}] if payer is not None else [],
|
|
"cpt": [{"code": c, "checked": True, "fee": "45.00"}
|
|
for c in codes]}
|
|
|
|
|
|
def _inject_cpt_row(page, code, row_id="CPTROW_3", checked=True, fee="45.00"):
|
|
page.evaluate(
|
|
"""(args) => {
|
|
const tbody = document.querySelector(
|
|
'#claimCPTCodesTable8888888888888 tbody');
|
|
const addRowTr = tbody.querySelector('tr:last-child');
|
|
const tr = document.createElement('tr');
|
|
tr.id = args.rowId;
|
|
tr.innerHTML =
|
|
'<td><input type="checkbox" ng-click="updateBillToIns(3)"'
|
|
+ (args.checked ? ' ng-checked="cpt.BillToIns==\\'1\\'" checked' : '')
|
|
+ '></td>'
|
|
+ '<td><input data-fieldname="claimCPTCode" value="' + args.code + '" readonly></td>'
|
|
+ '<td><input data-fieldname="ClaimCPTBilledFee" value="' + args.fee + '"></td>';
|
|
tbody.insertBefore(tr, addRowTr);
|
|
}""", {"code": code, "rowId": row_id, "checked": checked, "fee": fee})
|
|
|
|
|
|
# ── detect (no browser) ──────────────────────────────────────────────────────
|
|
|
|
@case
|
|
def detect_each_code_on_a_medicaid_claim():
|
|
for code in ("15851", "15852", "73521"):
|
|
assert cond.detect("C1", _claim("Medicaid", "99213", code)), code
|
|
|
|
|
|
@case
|
|
def detect_any_payer_in_the_medicaid_group():
|
|
assert cond.detect("C1", _claim("HCFA Medicaid", "73521")) is True
|
|
|
|
|
|
@case
|
|
def detect_ignores_spaces_around_the_code():
|
|
assert cond.detect("C1", _claim("Medicaid", " 15851 ")) is True
|
|
|
|
|
|
@case
|
|
def detect_false_on_any_other_payer():
|
|
# Operator, 2026-10-14: "Medicaid only, not RAE and others" — a payer of
|
|
# either RAE group (BH, Reporting Group) or CHP+ keeps the codes too.
|
|
for payer in ("Medicare", "AARP", "BH COLORADO ACCESS",
|
|
"Rocky Mountain Health Prime", "Child Health Plan Plus"):
|
|
assert cond.detect("C1", _claim(payer, "15851", "73521")) is False, \
|
|
payer
|
|
|
|
|
|
@case
|
|
def detect_false_on_an_unmapped_or_unread_payer():
|
|
assert cond.detect("C1", _claim("NO SUCH PAYER XYZ", "15851")) is False
|
|
assert cond.detect("C1", _claim("", "15851")) is False
|
|
assert cond.detect("C1", _claim(None, "15851")) is False
|
|
|
|
|
|
@case
|
|
def detect_false_on_a_medicaid_claim_without_the_codes():
|
|
assert cond.detect("C1", _claim("Medicaid", "99213", "73520")) is False
|
|
assert cond.detect("C1", {}) is False
|
|
|
|
|
|
# ── apply (browser) ──────────────────────────────────────────────────────────
|
|
|
|
@case
|
|
def apply_unchecks_and_zeroes_the_code_only(page):
|
|
page.goto(FIXTURE.as_uri())
|
|
_inject_cpt_row(page, "73521", checked=True, fee="120.00")
|
|
result = cond.apply(page, "C1", _claim("Medicaid", "73521"))
|
|
assert isinstance(result, ConditionResult)
|
|
assert result.condition_name == "medicaid_uncheck_cpts"
|
|
assert result.changed is True and len(result.changes) == 1, result
|
|
c = result.changes[0]
|
|
assert c["code"] == "73521" and c["unchecked"] is True, c
|
|
assert c["fee"] == {"before": "120.00", "after": "0.00"}, c
|
|
row = page.locator(sel.SEL_CPT_ROWS).nth(3)
|
|
assert row.locator(sel.SEL_CPT_ASSIGN_TO_PATIENT).first.is_checked() is False
|
|
assert row.locator(sel.SEL_CPT_BILLED_FEE).first.input_value() == "0.00"
|
|
first = page.locator(sel.SEL_CPT_ROWS).nth(0).locator(
|
|
sel.SEL_CPT_BILLED_FEE).first
|
|
assert first.input_value() == "210.00", "99213 must be left alone"
|
|
|
|
|
|
@case
|
|
def apply_handles_15851_and_15852_together(page):
|
|
page.goto(FIXTURE.as_uri())
|
|
_inject_cpt_row(page, "15851", row_id="CPTROW_3", fee="80.00")
|
|
_inject_cpt_row(page, "15852", row_id="CPTROW_4", fee="60.00")
|
|
result = cond.apply(page, "C1", _claim("Medicaid", "15851", "15852"))
|
|
by_code = {c["code"]: c for c in result.changes}
|
|
assert set(by_code) == {"15851", "15852"}, result.changes
|
|
assert by_code["15851"]["fee"] == {"before": "80.00", "after": "0.00"}
|
|
assert by_code["15852"]["fee"] == {"before": "60.00", "after": "0.00"}
|
|
|
|
|
|
@case
|
|
def apply_is_a_no_op_once_already_excluded(page):
|
|
page.goto(FIXTURE.as_uri())
|
|
_inject_cpt_row(page, "15851", checked=False, fee="0.00")
|
|
result = cond.apply(page, "C1", _claim("Medicaid", "15851"))
|
|
assert result.changed is False and result.changes == []
|
|
|
|
|
|
@case
|
|
def describe_names_the_code_and_the_fee_change(page):
|
|
page.goto(FIXTURE.as_uri())
|
|
_inject_cpt_row(page, "15852", fee="60.00")
|
|
text = cond.describe(cond.apply(page, "C1", _claim("Medicaid", "15852")))
|
|
assert "15852" in text and "60.00" in text and "0.00" in text, text
|
|
|
|
|
|
# ── wiring ───────────────────────────────────────────────────────────────────
|
|
|
|
@case
|
|
def it_is_registered_before_priced_line_check():
|
|
names = [m.NAME for m in CONDITIONS]
|
|
assert "medicaid_uncheck_cpts" in names
|
|
assert names.index("medicaid_uncheck_cpts") < names.index(
|
|
"priced_line_check"), names
|
|
|
|
|
|
@case
|
|
def the_charge_summary_has_its_comment():
|
|
assert "15851/15852/73521" in cs.COMMENTS["medicaid_uncheck_cpts"]
|
|
|
|
|
|
@case
|
|
def run_all_fires_it_on_a_medicaid_claim_and_not_on_medicare(page):
|
|
page.goto(FIXTURE.as_uri())
|
|
_inject_cpt_row(page, "73521", fee="120.00")
|
|
with contextlib.redirect_stdout(io.StringIO()):
|
|
results = run_all(page, "C1", _claim("Medicaid", "73521"))
|
|
assert [r.condition_name for r in results] == ["medicaid_uncheck_cpts"], \
|
|
results
|
|
page.goto(FIXTURE.as_uri())
|
|
_inject_cpt_row(page, "73521", fee="120.00")
|
|
with contextlib.redirect_stdout(io.StringIO()):
|
|
results = run_all(page, "C1", _claim("Medicare", "73521"))
|
|
assert "medicaid_uncheck_cpts" not in [r.condition_name
|
|
for r in results], results
|
|
row = page.locator(sel.SEL_CPT_ROWS).nth(3)
|
|
assert row.locator(sel.SEL_CPT_BILLED_FEE).first.input_value() == "120.00"
|
|
|
|
|
|
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())
|