Add preliminary daily accounting

This commit is contained in:
Reckless_Satoshi 2022-03-21 05:13:57 -07:00
parent 3d9ef5fc58
commit d4023bfd0d
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
5 changed files with 39 additions and 20 deletions

View File

@ -121,6 +121,7 @@ class UserProfileAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
"num_disputes", "num_disputes",
"lost_disputes", "lost_disputes",
) )
list_editable = ["pending_rewards", "earned_rewards"]
list_display_links = ("avatar_tag", "id") list_display_links = ("avatar_tag", "id")
change_links = ["user"] change_links = ["user"]
readonly_fields = ["avatar_tag"] readonly_fields = ["avatar_tag"]

View File

@ -111,7 +111,7 @@ def follow_send_payment(lnpayment):
lnpayment.save() lnpayment.save()
order.status = Order.Status.FAI order.status = Order.Status.FAI
order.expires_at = timezone.now() + timedelta( order.expires_at = timezone.now() + timedelta(
seconds=Order.t_to_expire[Order.Status.FAI]) seconds=order.t_to_expire(Order.Status.FAI))
order.save() order.save()
context = { context = {
"routing_failed": "routing_failed":
@ -127,7 +127,7 @@ def follow_send_payment(lnpayment):
lnpayment.save() lnpayment.save()
order.status = Order.Status.SUC order.status = Order.Status.SUC
order.expires_at = timezone.now() + timedelta( order.expires_at = timezone.now() + timedelta(
seconds=Order.t_to_expire[Order.Status.SUC]) seconds=order.t_to_expire(Order.Status.SUC))
order.save() order.save()
return True, None return True, None
@ -139,7 +139,7 @@ def follow_send_payment(lnpayment):
lnpayment.save() lnpayment.save()
order.status = Order.Status.FAI order.status = Order.Status.FAI
order.expires_at = timezone.now() + timedelta( order.expires_at = timezone.now() + timedelta(
seconds=Order.t_to_expire[Order.Status.FAI]) seconds=order.t_to_expire(Order.Status.FAI))
order.save() order.save()
context = {"routing_failed": "The payout invoice has expired"} context = {"routing_failed": "The payout invoice has expired"}
return False, context return False, context

View File

@ -22,7 +22,8 @@ class AccountingDayAdmin(ImportExportModelAdmin):
"outstanding_pending_disputes", "outstanding_pending_disputes",
"lifetime_rewards_claimed", "lifetime_rewards_claimed",
"outstanding_earned_rewards", "outstanding_earned_rewards",
"pending_disputes", "earned_rewards",
"disputes",
"rewards_claimed", "rewards_claimed",
) )
change_links = ["day"] change_links = ["day"]

View File

@ -32,7 +32,7 @@ class AccountingDay(models.Model):
# Balance change from last day on earned rewards (referral rewards, slashed bonds and solved disputes) # 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) earned_rewards = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Balance change on pending disputes (not resolved yet) # 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 on day
rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False) rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)

View File

@ -4,6 +4,7 @@ from control.models import AccountingDay, AccountingMonth
from django.utils import timezone from django.utils import timezone
from datetime import timedelta from datetime import timedelta
from django.db.models import Sum from django.db.models import Sum
from decouple import config
@shared_task(name="do_accounting") @shared_task(name="do_accounting")
def do_accounting(): def do_accounting():
@ -17,8 +18,10 @@ def do_accounting():
try: try:
last_accounted_day = AccountingDay.objects.latest('day').day.date() last_accounted_day = AccountingDay.objects.latest('day').day.date()
accounted_yesterday = AccountingDay.objects.latest('day')
except: except:
last_accounted_day = None last_accounted_day = None
accounted_yesterday = None
if last_accounted_day == today: if last_accounted_day == today:
return {'message':'no days to account for'} return {'message':'no days to account for'}
@ -30,11 +33,11 @@ def do_accounting():
day = initial_day day = initial_day
result = {} result = {}
accounted_yesterday = None
while day <= today: while day <= today:
day_payments = all_payments.filter(created_at__gte=day,created_at__lte=day+timedelta(days=1)) 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)) 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'] contracted = day_ticks.aggregate(Sum('volume'))['volume__sum']
num_contracts = day_ticks.count() num_contracts = day_ticks.count()
inflow = day_payments.filter(type=LNPayment.Types.HOLD,status=LNPayment.Status.SETLED).aggregate(Sum('num_satoshis'))['num_satoshis__sum'] 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, day = day,
contracted = contracted, contracted = contracted,
num_contracts = num_contracts, num_contracts = num_contracts,
net_settled = 0,
net_paid = 0,
net_balance = 0,
inflow = inflow, inflow = inflow,
outflow = outflow, outflow = outflow,
routing_fees = routing_fees, routing_fees = routing_fees,
@ -62,6 +62,31 @@ def do_accounting():
rewards_claimed = rewards_claimed, 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: if day == today:
pending_disputes = Order.objects.filter(status__in=[Order.Status.DIS,Order.Status.WFR]) pending_disputes = Order.objects.filter(status__in=[Order.Status.DIS,Order.Status.WFR])
if len(pending_disputes) > 0: 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'] accounted_day.lifetime_rewards_claimed = Profile.objects.all().aggregate(Sum('claimed_rewards'))['claimed_rewards__sum']
if accounted_yesterday != None: if accounted_yesterday != None:
accounted_day.earned_rewards = accounted_day.outstanding_earned_rewards - accounted_yesterday.outstanding_earned_rewards 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_day.save()
accounted_yesterday = accounted_day accounted_yesterday = accounted_day
result[str(day)]={'contracted':contracted,'inflow':inflow,'outflow':outflow} result[str(day)]={'contracted':contracted,'inflow':inflow,'outflow':outflow}
@ -84,12 +110,3 @@ def do_accounting():
return result return result
@shared_task(name="account_day")
def account_day():
'''
Does daily accounting since last accounted day.
To be run daily.
'''
return