diff --git a/api/admin.py b/api/admin.py index 3f9909a6..db2e118f 100644 --- a/api/admin.py +++ b/api/admin.py @@ -121,6 +121,7 @@ class UserProfileAdmin(AdminChangeLinksMixin, admin.ModelAdmin): "num_disputes", "lost_disputes", ) + list_editable = ["pending_rewards", "earned_rewards"] list_display_links = ("avatar_tag", "id") change_links = ["user"] readonly_fields = ["avatar_tag"] diff --git a/api/tasks.py b/api/tasks.py index 96895b91..6d9e0d79 100644 --- a/api/tasks.py +++ b/api/tasks.py @@ -111,7 +111,7 @@ def follow_send_payment(lnpayment): lnpayment.save() order.status = Order.Status.FAI order.expires_at = timezone.now() + timedelta( - seconds=Order.t_to_expire[Order.Status.FAI]) + seconds=order.t_to_expire(Order.Status.FAI)) order.save() context = { "routing_failed": @@ -127,7 +127,7 @@ def follow_send_payment(lnpayment): lnpayment.save() order.status = Order.Status.SUC order.expires_at = timezone.now() + timedelta( - seconds=Order.t_to_expire[Order.Status.SUC]) + seconds=order.t_to_expire(Order.Status.SUC)) order.save() return True, None @@ -139,7 +139,7 @@ def follow_send_payment(lnpayment): lnpayment.save() order.status = Order.Status.FAI order.expires_at = timezone.now() + timedelta( - seconds=Order.t_to_expire[Order.Status.FAI]) + seconds=order.t_to_expire(Order.Status.FAI)) order.save() context = {"routing_failed": "The payout invoice has expired"} return False, context diff --git a/control/admin.py b/control/admin.py index 84f9237f..c7416eab 100755 --- a/control/admin.py +++ b/control/admin.py @@ -22,7 +22,8 @@ class AccountingDayAdmin(ImportExportModelAdmin): "outstanding_pending_disputes", "lifetime_rewards_claimed", "outstanding_earned_rewards", - "pending_disputes", + "earned_rewards", + "disputes", "rewards_claimed", ) change_links = ["day"] diff --git a/control/models.py b/control/models.py index 2cd31bfa..82dd2678 100755 --- a/control/models.py +++ b/control/models.py @@ -32,7 +32,7 @@ class AccountingDay(models.Model): # Balance change from last day on earned rewards (referral rewards, slashed bonds and solved disputes) earned_rewards = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False) # Balance change on pending disputes (not resolved yet) - pending_disputes = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False) + disputes = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False) # Rewards claimed on day rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False) diff --git a/control/tasks.py b/control/tasks.py index ba55cad8..2ab940f9 100644 --- a/control/tasks.py +++ b/control/tasks.py @@ -4,6 +4,7 @@ from control.models import AccountingDay, AccountingMonth from django.utils import timezone from datetime import timedelta from django.db.models import Sum +from decouple import config @shared_task(name="do_accounting") def do_accounting(): @@ -17,8 +18,10 @@ def do_accounting(): try: last_accounted_day = AccountingDay.objects.latest('day').day.date() + accounted_yesterday = AccountingDay.objects.latest('day') except: last_accounted_day = None + accounted_yesterday = None if last_accounted_day == today: return {'message':'no days to account for'} @@ -30,11 +33,11 @@ def do_accounting(): day = initial_day result = {} - accounted_yesterday = None while day <= today: day_payments = all_payments.filter(created_at__gte=day,created_at__lte=day+timedelta(days=1)) day_ticks = all_ticks.filter(timestamp__gte=day,timestamp__lte=day+timedelta(days=1)) + # Coarse accounting based on LNpayment objects contracted = day_ticks.aggregate(Sum('volume'))['volume__sum'] num_contracts = day_ticks.count() inflow = day_payments.filter(type=LNPayment.Types.HOLD,status=LNPayment.Status.SETLED).aggregate(Sum('num_satoshis'))['num_satoshis__sum'] @@ -52,9 +55,6 @@ def do_accounting(): day = day, contracted = contracted, num_contracts = num_contracts, - net_settled = 0, - net_paid = 0, - net_balance = 0, inflow = inflow, outflow = outflow, routing_fees = routing_fees, @@ -62,6 +62,31 @@ def do_accounting(): rewards_claimed = rewards_claimed, ) + # Fine Net Daily accounting based on orders + # Only account for orders where everything worked out right + payouts = day_payments.filter(type=LNPayment.Types.NORM,concept=LNPayment.Concepts.PAYBUYER, status=LNPayment.Status.SUCCED) + escrows_settled = 0 + payouts_paid = 0 + routing_cost = 0 + for payout in payouts: + escrows_settled += payout.order_paid.trade_escrow.num_satoshis + payouts_paid += payout.num_satoshis + routing_cost += payout.fee + + # account for those orders where bonds were lost + # + Settled bonds / bond_split + bonds_settled = day_payments.filter(type=LNPayment.Types.HOLD,concept__in=[LNPayment.Concepts.TAKEBOND,LNPayment.Concepts.MAKEBOND], status=LNPayment.Status.SETLED) + + if len(bonds_settled) > 0: + collected_slashed_bonds = (bonds_settled.aggregate(Sum('num_satoshis'))['num_satoshis__sum'])* float(config('SLASHED_BOND_REWARD_SPLIT')) + else: + collected_slashed_bonds = 0 + + accounted_day.net_settled = escrows_settled + collected_slashed_bonds + accounted_day.net_paid = payouts_paid + routing_cost + accounted_day.net_balance = accounted_day.net_settled - accounted_day.net_paid + + # Differential accounting based on change of outstanding states and disputes unreslved if day == today: pending_disputes = Order.objects.filter(status__in=[Order.Status.DIS,Order.Status.WFR]) if len(pending_disputes) > 0: @@ -74,8 +99,9 @@ def do_accounting(): accounted_day.lifetime_rewards_claimed = Profile.objects.all().aggregate(Sum('claimed_rewards'))['claimed_rewards__sum'] if accounted_yesterday != None: accounted_day.earned_rewards = accounted_day.outstanding_earned_rewards - accounted_yesterday.outstanding_earned_rewards - accounted_day.pending_disputes = outstanding_pending_disputes - accounted_yesterday.outstanding_earned_rewards + accounted_day.disputes = outstanding_pending_disputes - accounted_yesterday.outstanding_earned_rewards + # Close the loop accounted_day.save() accounted_yesterday = accounted_day result[str(day)]={'contracted':contracted,'inflow':inflow,'outflow':outflow} @@ -83,13 +109,4 @@ def do_accounting(): - return result - -@shared_task(name="account_day") -def account_day(): - ''' - Does daily accounting since last accounted day. - To be run daily. - ''' - - return \ No newline at end of file + return result \ No newline at end of file