107 lines
3.1 KiB
Python
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
|