Skip to content

Commit

Permalink
Support no first payment when checking for debts. Fixes #174.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundobatista committed Apr 5, 2020
1 parent aed1c09 commit e68c8c3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 25 deletions.
30 changes: 20 additions & 10 deletions website/members/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,22 +133,32 @@ def create_recurring_payments(recurring_records):
def get_debt_state(member, limit_year, limit_month):
"""Return if the member is in debt, and the missing quotas.
The quotas verified are from first payment up to the given year/month limit (including).
If the member has a first payment, the quotas verified are from that first payment up
to the given year/month limit (including).
If the member never paid, the registration date is used, and that month is also included.
"""
if member.first_payment_year is None:
# never paid! using registration date to start with
yearmonths_paid = set()
year_to_check = member.registration_date.year
month_to_check = member.registration_date.month
else:
# build a set for the year/month of paid quotas
quotas = Quota.objects.filter(member=member).all()
yearmonths_paid = {(q.year, q.month) for q in quotas}

year_to_check = member.first_payment_year
month_to_check = member.first_payment_month

# verify the limit is after member started paying
if member.first_payment_year == limit_year:
if member.first_payment_month > limit_month:
if year_to_check == limit_year:
if month_to_check > limit_month:
return []
elif member.first_payment_year > limit_year:
elif year_to_check > limit_year:
return []

# build a set for the year/month of paid quotas
quotas = Quota.objects.filter(member=member).all()
yearmonths_paid = {(q.year, q.month) for q in quotas}

# build a set of all the year/month the member should have paid up to (including) the limit
year_to_check = member.first_payment_year
month_to_check = member.first_payment_month
should_have_paid = set()
while True:
should_have_paid.add((year_to_check, month_to_check))
Expand Down
53 changes: 38 additions & 15 deletions website/members/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@

from members import logic, views
from members.models import (
Member, Patron, Category, PaymentStrategy, Quota, Person,
Organization, Payment)
Category,
Member,
Organization,
Patron,
Payment,
PaymentStrategy,
Person,
Quota,
)
from .factories import (
PatronFactory,
QuotaFactory,
Expand All @@ -34,14 +41,15 @@ def create_category():
return category


def create_member(first_payment_year=None, first_payment_month=None, patron=None):
def create_member(
first_payment_year=None, first_payment_month=None, patron=None, registration_date=None):
"""Create a testing Member."""
first_payment_year = first_payment_year or 2017
first_payment_month = first_payment_month or 5
first_payment_year = first_payment_year
first_payment_month = first_payment_month
category = create_category()
return Member.objects.create(
first_payment_year=first_payment_year, first_payment_month=first_payment_month,
category=category, patron=patron)
category=category, patron=patron, registration_date=registration_date)


def create_patron(email=None):
Expand Down Expand Up @@ -215,7 +223,7 @@ class CreatePaymentTestCase(TestCase):

def test_first_payment(self):
# needed objects
member = create_member()
member = create_member(first_payment_year=2017, first_payment_month=5)
ps = create_payment_strategy()

# create the payment
Expand Down Expand Up @@ -295,7 +303,7 @@ def test_crossing_years(self):

def test_not_exact_amount_small(self):
# needed objects
member = create_member()
member = create_member(first_payment_year=2017, first_payment_month=5)
ps = create_payment_strategy()

# create the payment
Expand Down Expand Up @@ -346,7 +354,7 @@ def test_simple_empty(self):
# needed objects
payer_id = 'test@example.com'
ps = create_payment_strategy(platform=PaymentStrategy.MERCADO_PAGO, payer_id=payer_id)
member = create_member(patron=ps.patron)
member = create_member(patron=ps.patron, first_payment_year=2017, first_payment_month=5)

# create the payment
tstamp = make_aware(datetime.datetime(year=2017, month=2, day=5))
Expand All @@ -366,7 +374,7 @@ def test_simple_previous_payments(self):
# needed objects
payer_id = 'test@example.com'
ps = create_payment_strategy(platform=PaymentStrategy.MERCADO_PAGO, payer_id=payer_id)
member = create_member(patron=ps.patron)
member = create_member(patron=ps.patron, first_payment_year=2017, first_payment_month=5)

# create three payments in different timestamps
tstamp1 = make_aware(datetime.datetime(year=2017, month=2, day=5))
Expand Down Expand Up @@ -399,7 +407,7 @@ def test_simple_everything_previous(self):
# needed objects
payer_id = 'test@example.com'
ps = create_payment_strategy(platform=PaymentStrategy.MERCADO_PAGO, payer_id=payer_id)
create_member(patron=ps.patron)
create_member(patron=ps.patron, first_payment_year=2017, first_payment_month=5)

# create two payments in different timestamps
tstamp1 = make_aware(datetime.datetime(year=2017, month=2, day=5))
Expand Down Expand Up @@ -427,9 +435,9 @@ def test_multiple_payers(self):
payer_id1 = 'test@example.com'
payer_id2 = 'other@example.com'
ps = create_payment_strategy(platform=PaymentStrategy.MERCADO_PAGO, payer_id=payer_id1)
member1 = create_member(patron=ps.patron)
member1 = create_member(patron=ps.patron, first_payment_year=2017, first_payment_month=5)
ps = create_payment_strategy(platform=PaymentStrategy.MERCADO_PAGO, payer_id=payer_id2)
member2 = create_member(patron=ps.patron)
member2 = create_member(patron=ps.patron, first_payment_year=2017, first_payment_month=5)

# create the payment
tstampA = make_aware(datetime.datetime(year=2017, month=2, day=5))
Expand Down Expand Up @@ -497,7 +505,7 @@ def test_no_payment_match(self):
# needed objects
payer_id = 'test@example.com'
ps = create_payment_strategy(platform=PaymentStrategy.MERCADO_PAGO, payer_id=payer_id)
create_member(patron=ps.patron)
create_member(patron=ps.patron, first_payment_year=2017, first_payment_month=5)

# create two payments in different timestamps
tstamp1 = make_aware(datetime.datetime(year=2017, month=2, day=1))
Expand Down Expand Up @@ -588,6 +596,21 @@ def test_multiyear(self):
(2019, 7), (2019, 8), (2019, 9), (2019, 10), (2019, 11), (2019, 12),
(2020, 1), (2020, 2)])

def test_no_payment_yet_previous_month(self):
member = create_member(registration_date=datetime.date(2017, 5, 13))
debt = logic.get_debt_state(member, 2017, 1)
self.assertEqual(debt, [])

def test_no_payment_yet_registration_month(self):
member = create_member(registration_date=datetime.date(2017, 5, 13))
debt = logic.get_debt_state(member, 2017, 5)
self.assertEqual(debt, [(2017, 5)])

def test_no_payment_yet_several_months(self):
member = create_member(registration_date=datetime.date(2017, 5, 13))
debt = logic.get_debt_state(member, 2017, 8)
self.assertEqual(debt, [(2017, 5), (2017, 6), (2017, 7), (2017, 8)])


class BuildDebtStringTestCase(TestCase):
"""Tests for the string debt building utility."""
Expand Down Expand Up @@ -645,7 +668,7 @@ def test_get_members_list_page(self):
self.assertTemplateUsed(response, 'members/members_list.html')

def test_get_member_detail_page(self):
member = create_member()
member = create_member(first_payment_year=2017, first_payment_month=5)
response = self.client.get(reverse('member_detail', kwargs={"pk": member.pk}))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'members/member_detail.html')
Expand Down

0 comments on commit e68c8c3

Please sign in to comment.