{"files": {"main.py": "from core import run\nfrom policy import POLICY\ndef evaluate(payload):\n    return run(payload, POLICY)\n", "core.py": "import copy\nfrom helpers import principal_cents, dedupe_events, order_events\n\ndef run(payload, policy):\n    data = copy.deepcopy(payload)\n    if data is None:\n        raw_invoices = []\n    elif isinstance(data, dict):\n        raw_invoices = data.get('invoices') or []\n    elif isinstance(data, list):\n        raw_invoices = data\n    else:\n        raw_invoices = []\n    currency = policy.get('currency')\n    fee_refundable = policy.get('fee_refundable', False)\n    min_invoice_cents = policy.get('min_invoice_cents', 0)\n    status_case = policy.get('status_case', 'lower')\n    rounding = policy.get('rounding', 'per_line')\n    duplicate_event = policy.get('duplicate_event', 'first')\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', 'cap')\n    void_is_tombstone = policy.get('void_is_tombstone', False)\n    order = policy.get('order', 'id')\n    results = []\n    for invoice in raw_invoices:\n        if not isinstance(invoice, dict):\n            continue\n        if currency is not None and invoice.get('currency') != currency:\n            continue\n        lines = invoice.get('lines') or []\n        fee = int(invoice.get('fee_cents', 0) or 0)\n        principal = principal_cents(lines, rounding)\n        charge = principal + fee\n        if charge < min_invoice_cents:\n            continue\n        created = invoice.get('created', invoice.get('created_day', 0))\n        created = int(created) if created is not None else 0\n        events = invoice.get('events') or []\n        events = dedupe_events(events, duplicate_event)\n        events = order_events(events, refunds_first)\n        ceiling = charge if fee_refundable else principal\n        refunded = 0\n        active = True\n        tombstoned = False\n        for event in events:\n            if not isinstance(event, dict):\n                continue\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                else:\n                    active = False\n            elif kind == 'refund':\n                if not active:\n                    continue\n                day = event.get('day', 0)\n                day = int(day) if day is not None else 0\n                age = day - created\n                if age < 0:\n                    continue\n                if inclusive_limit:\n                    if age > max_age:\n                        continue\n                else:\n                    if age >= max_age:\n                        continue\n                amount = event.get('cents', event.get('amount_cents', 0))\n                amount = int(amount) if amount is not None else 0\n                if amount < 0:\n                    continue\n                remaining = ceiling - refunded\n                if remaining <= 0:\n                    continue\n                if refund_overflow == 'cap':\n                    refunded += min(amount, remaining)\n                else:\n                    if amount > remaining:\n                        continue\n                    refunded += amount\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() == 'title':\n            status = status.title()\n        else:\n            status = status.lower()\n        results.append({'id': invoice.get('id'), 'charge': charge, 'refunded': refunded, 'balance': charge - refunded, 'status': status, '_created': created})\n    if order in ('created', 'created_id', '(created,id)'):\n        results.sort(key=lambda x: (x['_created'], x['id']))\n    else:\n        results.sort(key=lambda x: x['id'])\n    invoices = [{'id': r['id'], 'charge': r['charge'], 'refunded': r['refunded'], 'balance': r['balance'], 'status': r['status']} for r in results]\n    return {'invoices': invoices}\n", "policy.py": "POLICY = {\n    \"currency\": \"USD\",\n    \"fee_refundable\": True,\n    \"min_invoice_cents\": 10,\n    \"status_case\": \"lower\",\n    \"rounding\": \"per_line\",\n    \"duplicate_event\": \"first\",\n    \"inclusive_limit\": True,\n    \"max_refund_age_days\": 30,\n    \"max_refund_age_days\": 30,\n    \"refunds_first\": True,\n    \"refund_overflow\": \"cap\",\n    \"void_is_tombstone\": True,\n    \"order\": \"id\",\n}\n", "helpers.py": "from decimal import Decimal, ROUND_HALF_UP\n\ndef _to_cents_decimal(line):\n    return Decimal(str(line)) * Decimal('100')\n\ndef principal_cents(lines, rounding):\n    if rounding == 'per_line':\n        total = 0\n        for line in lines:\n            cents = _to_cents_decimal(line).quantize(Decimal('1'), rounding=ROUND_HALF_UP)\n            total += int(cents)\n        return total\n    total_decimal = sum((_to_cents_decimal(line) for line in lines), Decimal('0'))\n    return int(total_decimal.quantize(Decimal('1'), rounding=ROUND_HALF_UP))\n\ndef dedupe_events(events, duplicate_event):\n    seen = {}\n    order = []\n    counter = 0\n    for event in events:\n        if isinstance(event, dict) and 'eid' in event:\n            key = event.get('eid')\n        else:\n            key = ('__no_eid__', counter)\n        counter += 1\n        if key not in seen:\n            seen[key] = event\n            order.append(key)\n        elif duplicate_event == 'last':\n            seen[key] = event\n    return [seen[key] for key in order]\n\ndef order_events(events, refunds_first):\n    if not refunds_first:\n        return list(events)\n    refunds = [e for e in events if isinstance(e, dict) and e.get('kind') == 'refund']\n    others = [e for e in events if not (isinstance(e, dict) and e.get('kind') == 'refund')]\n    return refunds + others\n"}}