{"files": {"main.py": "from core import run\nfrom policy import POLICY\ndef evaluate(payload):\n    return run(payload, POLICY)\n", "core.py": "from helpers import principal_cents, dedup_events\n\ndef _get(d, *names, default=None):\n    for n in names:\n        if isinstance(d, dict) and n in d:\n            return d[n]\n    return default\n\ndef run(payload, policy):\n    if payload is None:\n        invoices_in = []\n    elif isinstance(payload, list):\n        invoices_in = list(payload)\n    elif isinstance(payload, dict):\n        v = payload.get('invoices')\n        invoices_in = list(v) if isinstance(v, list) else []\n    else:\n        invoices_in = []\n    currency = policy.get('currency')\n    rounding = policy.get('rounding', 'invoice')\n    min_cents = policy.get('min_invoice_cents', 0)\n    if min_cents is None:\n        min_cents = 0\n    duplicate_event = policy.get('duplicate_event', 'last')\n    refunds_first = bool(policy.get('refunds_first', False))\n    fee_refundable = bool(policy.get('fee_refundable', False))\n    inclusive = bool(policy.get('inclusive_limit', False))\n    max_age = policy.get('max_refund_age_days')\n    overflow = policy.get('refund_overflow', 'reject')\n    tombstone_policy = bool(policy.get('void_is_tombstone', False))\n    status_case = policy.get('status_case', 'lower')\n    order = policy.get('order', 'id')\n    results = []\n    for inv in invoices_in:\n        if not isinstance(inv, dict):\n            continue\n        if currency is not None and inv.get('currency') != currency:\n            continue\n        inv_id = _get(inv, 'id')\n        created_raw = _get(inv, 'created', 'created_day', 'createdDay', default=0)\n        try:\n            created = int(created_raw)\n        except Exception:\n            created = 0\n        lines = _get(inv, 'lines', 'line_items', default=[])\n        if lines is None:\n            lines = []\n        lines = list(lines)\n        fee_raw = _get(inv, 'fee_cents', 'fee', default=0)\n        try:\n            fee = int(fee_raw)\n        except Exception:\n            fee = 0\n        principal = principal_cents(lines, rounding)\n        charge = principal + fee\n        if charge < min_cents:\n            continue\n        events_in = _get(inv, 'events', default=[])\n        if events_in is None:\n            events_in = []\n        events = dedup_events(list(events_in), duplicate_event)\n        if refunds_first:\n            refunds = [e for e in events if _get(e, 'kind', 'type') == 'refund']\n            others = [e for e in events if _get(e, 'kind', 'type') != 'refund']\n            events = refunds + others\n        active = True\n        tombstoned = False\n        refunded = 0\n        ceiling = principal + (fee if fee_refundable else 0)\n        for ev in events:\n            if not isinstance(ev, dict):\n                continue\n            kind = _get(ev, 'kind', 'type')\n            if kind == 'void':\n                active = False\n                if tombstone_policy:\n                    tombstoned = True\n            elif kind == 'restore':\n                if not tombstoned:\n                    active = True\n            elif kind == 'refund':\n                if not active:\n                    continue\n                day_raw = _get(ev, 'day', default=created)\n                try:\n                    day = int(day_raw)\n                except Exception:\n                    continue\n                age = day - created\n                if age < 0:\n                    continue\n                if max_age is not None:\n                    if inclusive:\n                        if age > max_age:\n                            continue\n                    else:\n                        if age >= max_age:\n                            continue\n                cents_raw = _get(ev, 'cents', 'amount_cents', 'amount', default=0)\n                try:\n                    cents = int(cents_raw)\n                except Exception:\n                    continue\n                if cents < 0:\n                    continue\n                if overflow == 'cap':\n                    remaining = ceiling - refunded\n                    if remaining > 0:\n                        refunded += cents if cents < remaining else remaining\n                else:\n                    if refunded + cents > ceiling:\n                        continue\n                    refunded += cents\n            else:\n                continue\n        if not active:\n            status = 'void'\n        elif refunded == charge:\n            status = 'refunded'\n        else:\n            status = 'open'\n        if isinstance(status_case, str) and status_case.lower() == 'upper':\n            status = status.upper()\n        elif isinstance(status_case, str) and status_case.lower() == 'lower':\n            status = status.lower()\n        elif isinstance(status_case, str) and status_case.lower() == 'title':\n            status = status.title()\n        item = {'id': inv_id, 'charge': charge, 'refunded': refunded, 'balance': charge - refunded, 'status': status}\n        results.append((created, inv_id, item))\n    if order == 'created':\n        results.sort(key=lambda t: (t[0], t[1]))\n    else:\n        results.sort(key=lambda t: t[1])\n    return {'invoices': [item for _, _, item in results]}\n", "policy.py": "POLICY = {\"currency\": \"CAD\", \"duplicate_event\": \"last\", \"fee_refundable\": False, \"inclusive_limit\": False, \"max_refund_age_days\": 45, \"min_invoice_cents\": 25, \"order\": \"created\", \"refund_overflow\": \"reject\", \"refunds_first\": False, \"rounding\": \"invoice\", \"status_case\": \"upper\", \"void_is_tombstone\": False}\n", "helpers.py": "from decimal import Decimal, ROUND_HALF_UP\n\ndef _to_cents_exact(amount):\n    return int((Decimal(str(amount)) * Decimal('100')).quantize(Decimal('1'), rounding=ROUND_HALF_UP))\n\ndef principal_cents(lines, rounding):\n    if rounding == 'per_line':\n        total = 0\n        for line in lines:\n            total += _to_cents_exact(line)\n        return total\n    total_dec = Decimal('0')\n    for line in lines:\n        total_dec += Decimal(str(line))\n    return int((total_dec * Decimal('100')).quantize(Decimal('1'), rounding=ROUND_HALF_UP))\n\ndef dedup_events(events, duplicate_event):\n    mode = duplicate_event if isinstance(duplicate_event, str) else 'last'\n    ordered = {}\n    no_eid = []\n    for idx, ev in enumerate(events):\n        if not isinstance(ev, dict):\n            continue\n        eid = ev.get('eid', ev.get('id')) if ('eid' in ev or 'id' in ev) else None\n        if eid is None:\n            no_eid.append((idx, ev))\n            continue\n        if mode == 'first':\n            if eid not in ordered:\n                ordered[eid] = ev\n        else:\n            ordered[eid] = ev\n    if not no_eid:\n        return list(ordered.values())\n    result = list(ordered.values())\n    for _, ev in no_eid:\n        result.append(ev)\n    return result\n"}}