            debts={k:D(v) for k,v in data['orders'].items()};byid={r['payment_id']:r for r in output['payments']};allocation=[];review=[]
            for payment in data['payments']:
                parsed=byid[payment['id']];left=D(payment['amount'])
                if parsed['ambiguous'] or any(oid not in debts for oid in parsed['order_ids']):review.append({'payment_id':payment['id'],'unallocated':money(left),'reason':'ambiguous-or-unknown-order'});continue
                for oid in parsed['order_ids']:
                    take=min(left,debts[oid]);allocation.append({'payment_id':payment['id'],'order_id':oid,'amount':money(take)});debts[oid]-=take;left-=take
                    if not left:break
                if left:review.append({'payment_id':payment['id'],'unallocated':money(left),'reason':'overpayment'})
            check('O1O2分配后均结清',debts['O1']==0 and debts['O2']==0);check('模糊汇款20元未擅自分配',review==[{'payment_id':'P3','unallocated':'20.00','reason':'ambiguous-or-unknown-order'}]);check('分配额加未分配额等于来款',sum(D(r['amount']) for r in allocation)+sum(D(r['unallocated']) for r in review)==sum(D(p['amount']) for p in data['payments']));cout('payment-allocation.csv',allocation);cout('payment-review.csv',review);result={'allocations':allocation,'review':review,'outstanding':{k:money(v) for k,v in debts.items()}}
