fix(835): correct SVC04/SVC05 mapping per X12 005010X221A1
X12 835 SVC segment: SVC01 = composite procedure SVC02 = charge SVC03 = payment SVC04 = Unit or Basis for Measurement Code (UN, MJ, DA, ...) SVC05 = Service Unit Count The parser previously read SVC04 as the units count and SVC05 as the unit type — backwards. On real 835s (and the canonical minimal fixture), SVC04 carries the code 'UN' which fails Decimal parsing, so the units always came out as None and the code string was assigned to unit_type. SP7's line-level matcher couldn't compare units on the SVC side against the claim side because of this. - _consume_service_payment: SVC04 → unit_type, SVC05 → units count - Default unit_type to 'UN' when only the count is present - minimal_835.txt + unbalanced_835.txt: swap positions to match spec - Add 2 regression tests (units-and-unit-type, default-unit-type-to-UN)
This commit is contained in:
@@ -304,21 +304,20 @@ def _consume_service_payment(segments: list[list[str]], idx: int, line_no: int)
|
||||
payment = Decimal(seg[3]) if len(seg) > 3 and seg[3] else Decimal("0")
|
||||
units: Decimal | None = None
|
||||
unit_type: str | None = None
|
||||
# X12 005010X221A1: SVC04 = Unit or Basis for Measurement Code
|
||||
# (UN, MJ, DA, ...); SVC05 = Service Unit Count.
|
||||
if len(seg) > 4 and seg[4]:
|
||||
# In X12 835, SVC04 is "units paid" and SVC05 is the unit-of-measure.
|
||||
# SVC05 may carry a value (UN, MJ, etc.) or be empty.
|
||||
unit_type = seg[4]
|
||||
if len(seg) > 5 and seg[5]:
|
||||
try:
|
||||
units = Decimal(seg[4])
|
||||
units = Decimal(seg[5])
|
||||
except Exception:
|
||||
units = None
|
||||
if len(seg) > 5 and seg[5]:
|
||||
unit_type = seg[5]
|
||||
elif len(seg) > 4 and seg[4]:
|
||||
# Some payers omit SVC05 but still mean "UN" when the units value
|
||||
# is present. Be conservative: only default to UN if no other value
|
||||
# was set above.
|
||||
if unit_type is None:
|
||||
unit_type = "UN"
|
||||
# Some payers omit SVC04 but still mean "UN" when SVC05 carries a
|
||||
# count. Be conservative: only default to UN if no other value was
|
||||
# set above.
|
||||
if unit_type is None and units is not None:
|
||||
unit_type = "UN"
|
||||
service_date: date | None = None
|
||||
ref_benefit_plan: str | None = None
|
||||
adjustments: list[ClaimAdjustment] = []
|
||||
|
||||
Reference in New Issue
Block a user