spaceport/apiserver/apiserver/api/utils.py

107 lines
3.1 KiB
Python

import datetime
from dateutil import relativedelta
from django.db.models import Sum
from . import models, old_models
def num_months_spanned(d1, d2):
'''
Return number of month thresholds two dates span.
Order of arguments is same as subtraction
ie. Feb 2, Jan 29 returns 1
'''
return (d1.year - d2.year) * 12 + d1.month - d2.month
def num_months_difference(d1, d2):
'''
Return number of whole months between two dates.
Order of arguments is same as subtraction
ie. Feb 2, Jan 29 returns 0
'''
r = relativedelta.relativedelta(d1, d2)
return r.months + 12 * r.years
def calc_member_status(expire_date, fake_date=None):
'''
Return: status, if we should pause them
'''
today = fake_date or datetime.date.today()
difference = num_months_difference(expire_date, today)
#if today + datetime.timedelta(days=29) < expire_date:
if difference >= 1:
return 'Prepaid', False
elif difference <= -3:
return 'Overdue', True
elif difference <= -1:
return 'Overdue', False
elif today < expire_date:
return 'Current', False
elif today >= expire_date:
return 'Due', False
else:
raise()
def add_months(date, num_months):
return date + relativedelta.relativedelta(months=num_months)
def fake_missing_membership_months(member):
'''
Add fake months on importing the member so the length of their membership
resolves to their imported expiry date
'''
start_date = member.current_start_date
expire_date = member.expire_date
missing_months = num_months_spanned(expire_date, start_date)
user = member.user if member.user else None
tx = False
for i in range(missing_months):
memo = '{} / {} month membership dues accounting old portal import, {} to {} - hidden'.format(
str(i+1), str(missing_months), start_date, expire_date
)
tx = models.Transaction.objects.create(
amount=0,
user=user,
memo=memo,
member_id=member.id,
reference_number='',
info_source='System',
payment_method='N/A',
category='Memberships:Fake Months',
account_type='Clearing',
number_of_membership_months=1,
date=add_months(start_date, i),
)
return tx
def tally_membership_months(member, fake_date=None):
'''
Sum together member's dues and calculate their new expire date and status
Doesn't work if member is paused.
'''
if member.paused_date: return False
start_date = member.current_start_date
if not start_date: return False
txs = models.Transaction.objects.filter(member_id=member.id)
total_months_agg = txs.aggregate(Sum('number_of_membership_months'))
total_months = total_months_agg['number_of_membership_months__sum'] or 0
expire_date = add_months(start_date, total_months)
status, former = calc_member_status(expire_date, fake_date)
member.expire_date = expire_date
member.status = status
if former:
member.paused_date = expire_date
member.save()
return True