feat(sp7): match_service_lines() pure function + tests

This commit is contained in:
Tyler
2026-06-20 19:29:21 -06:00
parent 8442bf91ce
commit 9626eae5f1
2 changed files with 222 additions and 0 deletions
+125
View File
@@ -0,0 +1,125 @@
"""SP7 — pure-function tests for match_service_lines().
Spec §4.
"""
from dataclasses import dataclass
from datetime import date
from decimal import Decimal
from cyclone.reconcile import (
LineMatch,
match_service_lines,
)
@dataclass
class FakeLine:
line_number: int
procedure_code: str
modifiers: list
service_date: date | None
units: Decimal | None
payment: Decimal = Decimal("0") # 835 only
@dataclass
class FakeClaimLine(FakeLine):
charge: Decimal = Decimal("0") # 837 only
def _claim(*lines: FakeClaimLine) -> list:
return list(lines)
def _remit(*lines: FakeLine) -> list:
return list(lines)
def test_exact_match_on_all_four_criteria():
claim_lines = _claim(FakeClaimLine(1, "99213", [], date(2026, 6, 1), Decimal("1")))
remit_lines = _remit(FakeLine(1, "99213", [], date(2026, 6, 1), Decimal("1"), payment=Decimal("80")))
matches = match_service_lines(claim_lines, remit_lines)
assert len(matches) == 1
assert matches[0].claim_line.line_number == 1
assert matches[0].service_payment.line_number == 1
assert matches[0].status == "matched"
def test_procedure_code_mismatch_both_unmatched():
claim_lines = _claim(FakeClaimLine(1, "99213", [], None, None))
remit_lines = _remit(FakeLine(1, "99214", [], None, None))
matches = match_service_lines(claim_lines, remit_lines)
assert len(matches) == 2
statuses = sorted(m.status for m in matches)
assert statuses == ["unmatched_835_only", "unmatched_837_only"]
def test_modifiers_set_equal_regardless_of_order():
claim_lines = _claim(FakeClaimLine(1, "99213", ["25", "59"], None, None))
remit_lines = _remit(FakeLine(1, "99213", ["59", "25"], None, None))
matches = match_service_lines(claim_lines, remit_lines)
assert len(matches) == 1
assert matches[0].status == "matched"
def test_service_date_mismatch():
claim_lines = _claim(FakeClaimLine(1, "99213", [], date(2026, 6, 1), None))
remit_lines = _remit(FakeLine(1, "99213", [], date(2026, 6, 2), None))
matches = match_service_lines(claim_lines, remit_lines)
assert len(matches) == 2
statuses = sorted(m.status for m in matches)
assert statuses == ["unmatched_835_only", "unmatched_837_only"]
def test_units_mismatch():
claim_lines = _claim(FakeClaimLine(1, "99213", [], None, Decimal("1")))
remit_lines = _remit(FakeLine(1, "99213", [], None, Decimal("2")))
matches = match_service_lines(claim_lines, remit_lines)
assert len(matches) == 2
statuses = sorted(m.status for m in matches)
assert statuses == ["unmatched_835_only", "unmatched_837_only"]
def test_procedure_code_case_normalized():
claim_lines = _claim(FakeClaimLine(1, "99213", [], None, None))
remit_lines = _remit(FakeLine(1, "99213", [], None, None)) # case irrelevant when both upper
matches = match_service_lines(claim_lines, remit_lines)
assert matches[0].status == "matched"
def test_claim_has_more_lines_than_remit():
claim_lines = _claim(
FakeClaimLine(1, "99213", [], None, None),
FakeClaimLine(2, "99214", [], None, None),
)
remit_lines = _remit(FakeLine(1, "99213", [], None, None))
matches = match_service_lines(claim_lines, remit_lines)
statuses = sorted(m.status for m in matches)
assert statuses == ["matched", "unmatched_837_only"]
def test_remit_has_more_lines_than_claim():
claim_lines = _claim(FakeClaimLine(1, "99213", [], None, None))
remit_lines = _remit(
FakeLine(1, "99213", [], None, None),
FakeLine(2, "99214", [], None, None),
)
matches = match_service_lines(claim_lines, remit_lines)
statuses = sorted(m.status for m in matches)
assert statuses == ["matched", "unmatched_835_only"]
def test_empty_837_lines_no_reconciliation_rows():
matches = match_service_lines([], _remit(FakeLine(1, "99213", [], None, None)))
assert len(matches) == 1
assert matches[0].status == "unmatched_835_only"
def test_empty_835_lines_no_reconciliation_rows():
matches = match_service_lines(_claim(FakeClaimLine(1, "99213", [], None, None)), [])
assert len(matches) == 1
assert matches[0].status == "unmatched_837_only"
def test_both_empty():
assert match_service_lines([], []) == []