from data.diff_result import FieldResult from decimal import Decimal, InvalidOperation DEFAULT_TOLERANCE = 0.01 def compare_field(name: str, c: str, j: str, field_type: str = "decimal", tolerance: float = DEFAULT_TOLERANCE) -> FieldResult: fr = FieldResult(field_name=name, cobol_value=c, java_value=j) if field_type in ("decimal", "numeric"): return _numeric(fr, c, j, tolerance) if field_type == "date": return _date(fr, c, j) if field_type == "string": return _string(fr, c, j) fr.status = "PASS" if c == j else "MISMATCH" return fr def _numeric(fr, c, j, tol): cv = _num(c) jv = _num(j) if cv is None or jv is None: fr.status = "NOT_SET" if cv is None and jv is None else ( "MISMATCH" if jv is None else "NOT_SET") return fr if cv == jv: fr.status = "PASS" return fr diff = abs(float(cv - jv)) if diff <= tol: fr.status = "TOLERATED" fr.tolerance_applied = tol else: fr.status = "MISMATCH" return fr def _date(fr, c, j): def _norm(v): v = v.strip() if len(v) == 8 and v.isdigit(): return f"{v[:4]}-{v[4:6]}-{v[6:8]}" return v fr.status = "PASS" if _norm(c) == _norm(j) else "MISMATCH" return fr def _string(fr, c, j): fr.status = "PASS" if (c or "").strip() == (j or "").strip() else "MISMATCH" return fr def _num(v): if v is None or v == "None": return None s = str(v).replace("\x00", "").strip() if s == "": return Decimal("0") try: return Decimal(s) except InvalidOperation: return None