{"files":{"main.py":"from core import run\nfrom policy import POLICY\n\n\ndef evaluate(payload):\n    return run(payload, POLICY)\n","core.py":"from helpers import principal_cents\n\n\ndef run(payload, policy):\n    invoices = payload.get('invoices', []) if isinstance(payload, dict) else (payload or [])\n    results = []\n    for invoice in invoices:\n        if invoice['currency'] != policy['currency']:\n            continue\n        principal = principal_cents(invoice['lines'], policy['rounding'])\n        fee = invoice.get('fee_cents', 0)\n        charge = principal + fee\n        if charge < policy['min_invoice_cents']:\n            continue\n\n        unique = {}\n        for event in invoice.get('events', []):\n            eid = event['eid']\n            if eid not in unique or policy['duplicate_event'] == 'last':\n                unique[eid] = event\n        events = list(unique.values())\n        if policy['refunds_first']:\n            events = [e for e in events if e['kind'] == 'refund'] + [e for e in events if e['kind'] != 'refund']\n\n        active = True\n        tombstone = False\n        refunded = 0\n        ceiling = principal + (fee if policy['fee_refundable'] else 0)\n        for event in events:\n            kind = event['kind']\n            if kind == 'void':\n                active = False\n                if policy['void_is_tombstone']:\n                    tombstone = True\n            elif kind == 'restore':\n                if not tombstone:\n                    active = True\n            elif kind == 'refund' and active:\n                age = event['day'] - invoice['created']\n                limit = policy['max_refund_age_days']\n                if age < 0 or age > limit or (age == limit and not policy['inclusive_limit']):\n                    continue\n                amount = event['cents']\n                remaining = ceiling - refunded\n                if amount > remaining:\n                    if policy['refund_overflow'] == 'reject':\n                        continue\n                    amount = remaining\n                refunded += amount\n\n        status = 'void' if not active else ('refunded' if refunded == charge else 'open')\n        status = status.upper() if policy['status_case'] == 'upper' else status.lower()\n        result = {'id': invoice['id'], 'charge': charge, 'refunded': refunded, 'balance': charge - refunded, 'status': status}\n        results.append((invoice['created'], result))\n\n    if policy['order'] == 'id':\n        results.sort(key=lambda item: item[1]['id'])\n    else:\n        results.sort(key=lambda item: (item[0], item[1]['id']))\n    return {'invoices': [result for _, result 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\n\n\ndef decimal_cent_parts(value):\n    parts = Decimal(value).as_tuple()\n    coefficient = 0\n    for digit in parts.digits:\n        coefficient = coefficient * 10 + digit\n    return coefficient, parts.exponent + 2\n\n\ndef rounded_sum(parts):\n    scale = min([0] + [exponent for _, exponent in parts])\n    numerator = sum(coefficient * 10 ** (exponent - scale) for coefficient, exponent in parts)\n    denominator = 10 ** (-scale)\n    return (2 * numerator + denominator) // (2 * denominator)\n\n\ndef principal_cents(lines, rounding):\n    parts = [decimal_cent_parts(line) for line in lines]\n    if rounding == 'per_line':\n        return sum(rounded_sum([part]) for part in parts)\n    return rounded_sum(parts)\n"}}