{"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 compute_principal_cents, deduplicate_events, order_events, format_status\n\ndef run(payload, policy):\n    if not payload:\n        return {\"invoices\": []}\n    invoices_in = payload.get(\"invoices\") or []\n    currency = policy.get(\"currency\")\n    rounding = policy.get(\"rounding\")\n    min_invoice_cents = policy.get(\"min_invoice_cents\", 0)\n    duplicate_event = policy.get(\"duplicate_event\")\n    refunds_first = policy.get(\"refunds_first\", False)\n    void_is_tombstone = policy.get(\"void_is_tombstone\", False)\n    max_refund_age_days = policy.get(\"max_refund_age_days\")\n    inclusive_limit = policy.get(\"inclusive_limit\", False)\n    fee_refundable = policy.get(\"fee_refundable\", False)\n    refund_overflow = policy.get(\"refund_overflow\")\n    status_case = policy.get(\"status_case\")\n    order = policy.get(\"order\")\n    records = []\n    for inv in invoices_in:\n        if inv.get(\"currency\") != currency:\n            continue\n        lines = inv.get(\"lines\") or []\n        fee = inv.get(\"fee_cents\", 0)\n        principal = compute_principal_cents(lines, rounding)\n        charge = principal + fee\n        if charge < min_invoice_cents:\n            continue\n        created = inv.get(\"created\")\n        events = deduplicate_events(inv.get(\"events\") or [], duplicate_event)\n        events = order_events(events, refunds_first)\n        ceiling = principal + (fee if fee_refundable else 0)\n        active = True\n        tombstoned = False\n        refunded = 0\n        for event in events:\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                age = event.get(\"day\") - created\n                if age < 0:\n                    continue\n                if inclusive_limit:\n                    if age > max_refund_age_days:\n                        continue\n                else:\n                    if age >= max_refund_age_days:\n                        continue\n                cents = event.get(\"cents\", 0)\n                if refund_overflow == \"cap\":\n                    remaining = ceiling - refunded\n                    if remaining <= 0:\n                        continue\n                    refunded += cents if cents < remaining else remaining\n                else:\n                    if refunded + cents > ceiling:\n                        continue\n                    refunded += cents\n        status = format_status(active, refunded, charge, status_case)\n        output = {\"id\": inv.get(\"id\"), \"charge\": charge, \"refunded\": refunded, \"balance\": charge - refunded, \"status\": status}\n        records.append((created, inv.get(\"id\"), output))\n    if order == \"id\":\n        records.sort(key=lambda item: item[1])\n    else:\n        records.sort(key=lambda item: (item[0], item[1]))\n    return {\"invoices\": [item[2] for item in records]}\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 compute_principal_cents(lines, rounding):\n    decimals = [Decimal(str(line)) for line in lines]\n    if rounding == \"per_line\":\n        total = 0\n        for value in decimals:\n            total += int((value * Decimal(100)).quantize(Decimal(\"1\"), rounding=ROUND_HALF_UP))\n        return total\n    total_decimal = sum(decimals, Decimal(0))\n    return int((total_decimal * Decimal(100)).quantize(Decimal(\"1\"), rounding=ROUND_HALF_UP))\n\ndef deduplicate_events(events, mode):\n    ordered = {}\n    for event in events:\n        eid = event.get(\"eid\")\n        if mode == \"last\":\n            ordered[eid] = event\n        else:\n            if eid not in ordered:\n                ordered[eid] = event\n    return list(ordered.values())\n\ndef order_events(events, refunds_first):\n    if not refunds_first:\n        return list(events)\n    refunds = [event for event in events if event.get(\"kind\") == \"refund\"]\n    others = [event for event in events if event.get(\"kind\") != \"refund\"]\n    return refunds + others\n\ndef format_status(active, refunded, charge, status_case):\n    if not active:\n        base = \"void\"\n    elif refunded == charge:\n        base = \"refunded\"\n    else:\n        base = \"open\"\n    if status_case == \"upper\":\n        return base.upper()\n    if status_case == \"lower\":\n        return base.lower()\n    if status_case == \"title\":\n        return base.title()\n    if status_case == \"capitalize\":\n        return base.capitalize()\n    return base\n"}}