def create_payouts(): """ Groups payable payouts at the end of the day by currency for easier paying out and database compaction, allowing deletion of regular payout records. """ grouped_credits = {} payout_summary = {} q = Credit.query.filter_by(payable=True, payout_id=None).all() for credit in q: key = (credit.currency, credit.user, credit.address) lst = grouped_credits.setdefault(key, []) lst.append(credit) # Round down to a payable amount (1 satoshi) + record remainder for (currency, user, address), credits in grouped_credits.iteritems(): total = sum([credit.payable_amount for credit in credits]) if total < currencies[currency].minimum_payout: current_app.logger.info( "Skipping payout gen of {} for {} because insuff minimum" .format(currency, user)) continue payout = Payout(currency=currency, user=user, address=address, amount=total, count=len(credits)) db.session.add(payout) db.session.flush() for credit in credits: credit.payout = payout amt_payable = payout.amount.quantize( current_app.SATOSHI, rounding=decimal.ROUND_DOWN) extra = payout.amount - amt_payable payout.amount = amt_payable if extra > 0: # Generate a new credit to catch fractional amounts in the next # payout p = Credit(user=user, amount=extra, fee_perc=0, source=3, pd_perc=0, currency=currency, address=address, payable=True) db.session.add(p) current_app.logger.info( "Created payout for {} {} with remainder of {}" .format(currency, user, extra)) payout_summary.setdefault(currency, 0) payout_summary[currency] += payout.amount current_app.logger.info("############### SUMMARY OF PAYOUTS GENERATED #####################") current_app.logger.info(pprint(payout_summary)) db.session.commit()