{"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, deduplicate_events, format_status\n\ndef run(payload, policy):\n    if payload is None:\n        invoices_in = []\n    elif isinstance(payload, dict):\n        invoices_in = payload.get('invoices') or []\n    elif isinstance(payload, (list, tuple)):\n        invoices_in = list(payload)\n    else:\n        invoices_in = []\n    currency = policy.get('currency')\n    fee_refundable = policy.get('fee_refundable', False)\n    min_invoice_cents = policy.get('min_invoice_cents', 0)\n    rounding = policy.get('rounding', 'invoice')\n    duplicate_event = policy.get('duplicate_event', 'last')\n    inclusive_limit = policy.get('inclusive_limit', False)\n    max_age = policy.get('max_refund_age_days', policy.get('max_refund_age_days', 0))\n    refunds_first = policy.get('refunds_first', False)\n    refund_overflow = policy.get('refund_overflow', 'reject')\n    void_is_tombstone = policy.get('void_is_tombstone', False)\n    order = policy.get('order', 'created')\n    status_case = policy.get('status_case', 'upper')\n    results = []\n    for invoice in invoices_in:\n        if not isinstance(invoice, dict):\n            continue\n        if invoice.get('currency') != currency:\n            continue\n        invoice_id = invoice.get('id')\n        created = invoice.get('created')\n        lines = invoice.get('lines') or []\n        fee_cents = invoice.get('fee_cents') or 0\n        principal = principal_cents(lines, rounding)\n        charge = principal + int(fee_cents)\n        if charge < min_invoice_cents:\n            continue\n        events = invoice.get('events') or []\n        deduped = deduplicate_events(events, duplicate_event)\n        if refunds_first:\n            deduped = sorted(deduped, key=lambda e: 0 if e.get('kind') == 'refund' else 1)\n        ceiling = charge if fee_refundable else principal\n        active = True\n        tombstoned = False\n        refunded = 0\n        for event in deduped:\n            kind = event.get('kind')\n            if kind == 'void':\n                active = False\n                if void_is_tombstone:\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 = event.get('day')\n                try:\n                    age = day - created\n                except Exception:\n                    continue\n                if inclusive_limit:\n                    if not (0 <= age <= max_age):\n                        continue\n                else:\n                    if not (0 <= age < max_age):\n                        continue\n                cents = event.get('cents') or 0\n                cents = int(cents)\n                if refunded + cents > ceiling:\n                    if refund_overflow == 'cap':\n                        refunded = ceiling\n                    continue\n                refunded += cents\n        if not active:\n            base_status = 'void'\n        elif refunded == charge:\n            base_status = 'refunded'\n        else:\n            base_status = 'open'\n        item = {'id': invoice_id, 'charge': charge, 'refunded': refunded, 'balance': charge - refunded, 'status': format_status(base_status, status_case)}\n        results.append((created, invoice_id, item))\n    if order == 'created':\n        results.sort(key=lambda x: (x[0], x[1]))\n    else:\n        results.sort(key=lambda x: x[1])\n    return {'invoices': [item for _, _, item in results]}\n", "policy.py": "POLICY = {\n    'currency': 'CAD',\n    'fee_refundable': False,\n    'min_invoice_cents': 25,\n    'status_case': 'upper',\n    'rounding': 'invoice',\n    'duplicate_event': 'last',\n    'inclusive_limit': False,\n    'max_refund_age_days': 45,\n    'refunds_first': False,\n    'refund_overflow': 'reject',\n    'void_is_tombstone': False,\n    'order': 'created',\n}\n", "helpers.py": "from decimal import Decimal, ROUND_HALF_UP\n\ndef _to_cents(amount):\n    return int((amount * Decimal('100')).quantize(Decimal('1'), rounding=ROUND_HALF_UP))\n\ndef principal_cents(lines, rounding):\n    decimals = [Decimal(str(line)) for line in lines]\n    if rounding == 'per_line':\n        return sum(_to_cents(value) for value in decimals)\n    return _to_cents(sum(decimals, Decimal('0')))\n\ndef deduplicate_events(events, mode):\n    ordered = {}\n    for index, event in enumerate(events):\n        if isinstance(event, dict) and 'eid' in event:\n            key = event.get('eid')\n        else:\n            key = ('__index__', index)\n        if mode == 'last':\n            ordered[key] = event\n        else:\n            if key not in ordered:\n                ordered[key] = event\n    return list(ordered.values())\n\ndef format_status(status, status_case):\n    if status_case == 'upper':\n        return status.upper()\n    if status_case == 'lower':\n        return status.lower()\n    if status_case == 'title':\n        return status.title()\n    return status\n"}}