Source code for example_checkout.tests.test_object_payment_plan_instalment

# -*- encoding: utf-8 -*-
import pytest

from datetime import date
from dateutil.relativedelta import relativedelta
from decimal import Decimal
from django.contrib.contenttypes.models import ContentType
from django.db import transaction
from freezegun import freeze_time

from checkout.models import (
    Checkout,
    CheckoutError,
    CheckoutAction,
    CheckoutState,
    Customer,
    ObjectPaymentPlan,
    ObjectPaymentPlanInstalment,
)
from checkout.tests.factories import (
    CheckoutFactory,
    ObjectPaymentPlanFactory,
    ObjectPaymentPlanInstalmentFactory,
    PaymentPlanFactory,
)
from checkout.tests.helper import check_checkout
from example_checkout.tests.factories import ContactFactory, SalesLedgerFactory
from login.tests.factories import UserFactory
from mail.models import Message
from mail.tests.factories import (
    MailTemplateFactory,
    MailFactory,
    MessageFactory,
)


[docs]@pytest.mark.django_db def test_audit_content_object(): obj = ObjectPaymentPlanInstalmentFactory( object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) ) CheckoutFactory( action=CheckoutAction.objects.charge, content_object=SalesLedgerFactory(), ) checkout = CheckoutFactory( action=CheckoutAction.objects.charge, content_object=obj ) result = Checkout.objects.audit_content_object(obj) assert [checkout.pk] == [o.pk for o in result]
[docs]@pytest.mark.django_db def test_audit_content_type(): obj = ObjectPaymentPlanInstalmentFactory( object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) ) CheckoutFactory( action=CheckoutAction.objects.charge, content_object=SalesLedgerFactory(), ) checkout = CheckoutFactory( action=CheckoutAction.objects.charge, content_object=obj ) result = Checkout.objects.audit_content_type( ContentType.objects.get_for_model(ObjectPaymentPlanInstalment) ) assert [checkout.pk] == [o.pk for o in result]
[docs]@pytest.mark.django_db def test_can_charge_deposit_fail(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( deposit=True, due=date.today(), object_payment_plan=object_payment_plan, state=CheckoutState.objects.fail, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_deposit_pending(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( deposit=True, due=date.today(), object_payment_plan=object_payment_plan, state=CheckoutState.objects.pending, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_deposit_not_pending(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( deposit=True, due=date.today(), object_payment_plan=object_payment_plan, state=CheckoutState.objects.request, ) assert not obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_due(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( due=date.today(), object_payment_plan=object_payment_plan, state=CheckoutState.objects.request, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_overdue(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( due=date.today() + relativedelta(days=-10), object_payment_plan=object_payment_plan, state=CheckoutState.objects.request, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_due_not_yet(): """The payment is not due yet, so can we charge? PJK 18/03/2016 Changing the behaviour of the ``checkout_can_charge`` method on ``ObjectPaymentPlanInstalment``. We want to allow a member of staff to charge the card for payments which are not yet due. The automated routine uses the ``due`` method so it shouldn't take payments early. """ object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( due=date.today() + relativedelta(days=10), object_payment_plan=object_payment_plan, state=CheckoutState.objects.request, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_fail(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( object_payment_plan=object_payment_plan, state=CheckoutState.objects.fail, ) assert not obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_not_deposit(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( due=date.today(), object_payment_plan=object_payment_plan, state=CheckoutState.objects.pending, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_pending(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( due=date.today() + relativedelta(days=-1), object_payment_plan=object_payment_plan, state=CheckoutState.objects.pending, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_pending_plan_deleted(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory(), deleted=True ) obj = ObjectPaymentPlanInstalmentFactory( due=date.today() + relativedelta(days=-1), object_payment_plan=object_payment_plan, state=CheckoutState.objects.pending, ) assert not obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_request(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( object_payment_plan=object_payment_plan, state=CheckoutState.objects.request, ) assert obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_charge_success(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( object_payment_plan=object_payment_plan, state=CheckoutState.objects.success, ) assert not obj.checkout_can_charge
[docs]@pytest.mark.django_db def test_can_mark_paid(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) obj = ObjectPaymentPlanInstalmentFactory( object_payment_plan=object_payment_plan, state=CheckoutState.objects.pending, ) assert obj.can_mark_paid is True
[docs]@pytest.mark.django_db def test_can_mark_paid_deleted(): object_payment_plan = ObjectPaymentPlanFactory( content_object=SalesLedgerFactory(), deleted=True ) obj = ObjectPaymentPlanInstalmentFactory( object_payment_plan=object_payment_plan, state=CheckoutState.objects.pending, ) assert obj.can_mark_paid is False
[docs]@pytest.mark.django_db def test_check_checkout(): with transaction.atomic(): # this must be run within a transaction obj = ObjectPaymentPlan.objects.create_object_payment_plan( SalesLedgerFactory(), PaymentPlanFactory(), Decimal("100") ) instalment = ObjectPaymentPlanInstalment.objects.get( object_payment_plan=obj ) check_checkout(instalment)
[docs]@pytest.mark.django_db def test_checkout_description(): payment_plan = PaymentPlanFactory( name="pkimber", deposit=50, count=2, interval=1 ) # create the plan and the deposit contact_pp = ObjectPaymentPlan.objects.create_object_payment_plan( SalesLedgerFactory(), payment_plan, Decimal("100") ) # check deposit description deposit = ObjectPaymentPlanInstalment.objects.filter( object_payment_plan=contact_pp ) assert 1 == deposit.count() assert ["deposit"] == deposit[0].checkout_description # create the instalments contact_pp.create_instalments() # check instalments = ObjectPaymentPlanInstalment.objects.filter( object_payment_plan=contact_pp ) assert 3 == instalments.count() assert ["1 of 2 instalments"] == instalments[1].checkout_description
[docs]@pytest.mark.django_db def test_checkout_fail(): with transaction.atomic(): # this must be run within a transaction obj = ObjectPaymentPlan.objects.create_object_payment_plan( SalesLedgerFactory(), PaymentPlanFactory(), Decimal("100") ) obj = ObjectPaymentPlanInstalment.objects.get(object_payment_plan=obj) checkout = CheckoutFactory( action=CheckoutAction.objects.charge, content_object=obj, state=CheckoutState.objects.fail, ) assert CheckoutState.objects.pending == obj.state obj.checkout_fail(checkout) assert CheckoutState.objects.fail == obj.state
[docs]@pytest.mark.django_db def test_checkout_name(): user = UserFactory(first_name="Patrick", last_name="Kimber") contact = ContactFactory(user=user) pp = ObjectPaymentPlan.objects.create_object_payment_plan( SalesLedgerFactory(contact=contact), PaymentPlanFactory(), Decimal("100"), ) obj = ObjectPaymentPlanInstalment.objects.get(object_payment_plan=pp) assert "Patrick Kimber" == obj.checkout_name
[docs]@pytest.mark.django_db def test_checkout_success(): contact_pp = ObjectPaymentPlan.objects.create_object_payment_plan( SalesLedgerFactory(), PaymentPlanFactory(), Decimal("100") ) obj = ObjectPaymentPlanInstalment.objects.get( object_payment_plan=contact_pp ) assert CheckoutState.objects.pending == obj.state checkout = CheckoutFactory( action=CheckoutAction.objects.charge, content_object=obj, state=CheckoutState.objects.success, ) obj.checkout_success(checkout) assert CheckoutState.objects.success == obj.state
[docs]@pytest.mark.django_db def test_checkout_total(): payment_plan = PaymentPlanFactory( name="pkimber", deposit=50, count=2, interval=1 ) user = UserFactory(first_name="Patrick", last_name="Kimber") contact = ContactFactory(user=user) pp = ObjectPaymentPlan.objects.create_object_payment_plan( SalesLedgerFactory(contact=contact), payment_plan, Decimal("100") ) pp.create_instalments() assert ( Decimal("50") == ObjectPaymentPlanInstalment.objects.get(count=1).checkout_total ) assert ( Decimal("25") == ObjectPaymentPlanInstalment.objects.get(count=2).checkout_total ) assert ( Decimal("25") == ObjectPaymentPlanInstalment.objects.get(count=3).checkout_total )
[docs]@pytest.mark.django_db def test_checkout_email(): user = UserFactory(email="me@test.com") contact = ContactFactory(user=user) pp = ObjectPaymentPlan.objects.create_object_payment_plan( SalesLedgerFactory(contact=contact), PaymentPlanFactory(), Decimal("100"), ) obj = ObjectPaymentPlanInstalment.objects.get(object_payment_plan=pp) assert "me@test.com" == obj.checkout_email
[docs]@pytest.mark.django_db def test_current_instalment(): plan = ObjectPaymentPlanFactory(content_object=SalesLedgerFactory()) today = date.today() ObjectPaymentPlanInstalmentFactory( count=1, deposit=True, due=today + relativedelta(days=1), object_payment_plan=plan, ) obj = ObjectPaymentPlanInstalmentFactory( count=2, due=today + relativedelta(days=2), object_payment_plan=plan ) assert 1 == obj.current_instalment
[docs]@pytest.mark.django_db def test_current_instalment_count(): plan = ObjectPaymentPlanFactory(content_object=SalesLedgerFactory()) today = date.today() ObjectPaymentPlanInstalmentFactory( count=1, deposit=True, due=today + relativedelta(days=1), object_payment_plan=plan, ) obj = ObjectPaymentPlanInstalmentFactory( count=0, due=today + relativedelta(days=2), object_payment_plan=plan ) with pytest.raises(CheckoutError) as e: obj.current_instalment assert "'count' value for an instalment should be greater" in str(e.value)
[docs]@pytest.mark.django_db def test_current_instalment_deposit(): plan = ObjectPaymentPlanFactory(content_object=SalesLedgerFactory()) today = date.today() obj = ObjectPaymentPlanInstalmentFactory( count=1, deposit=True, due=today + relativedelta(days=1), object_payment_plan=plan, ) with pytest.raises(CheckoutError) as e: obj.current_instalment assert "Cannot ask the deposit record" in str(e.value)
# @pytest.mark.django_db # def test_checkout_list(): # c1 = CheckoutFactory( # action=CheckoutAction.objects.charge, # content_object=SalesLedgerFactory(), # ) # c2 = CheckoutFactory( # action=CheckoutAction.objects.charge, # content_object=ObjectPaymentPlanInstalmentFactory( # object_payment_plan=ObjectPaymentPlanFactory( # content_object=SalesLedgerFactory(), # ), # ), # ) # c3 = CheckoutFactory( # action=CheckoutAction.objects.charge, # content_object=ObjectPaymentPlanInstalmentFactory( # object_payment_plan=ObjectPaymentPlanFactory( # content_object=SalesLedgerFactory(), # ), # ), # ) # checkout_list = ObjectPaymentPlanInstalment.objects.checkout_list # assert 2 == checkout_list.count() # assert c1 not in checkout_list # assert c2 in checkout_list # assert c3 in checkout_list
[docs]@pytest.mark.django_db def test_due(): today = date.today() ObjectPaymentPlanInstalmentFactory( count=1, due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( count=2, due=today + relativedelta(days=-2), amount=Decimal("2"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] assert [Decimal("1"), Decimal("2")] == result
[docs]@pytest.mark.django_db def test_due_fail_retry(): today = date.today() ObjectPaymentPlanInstalmentFactory( count=1, due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( count=2, due=today + relativedelta(days=-2), amount=Decimal("2"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( count=3, due=today + relativedelta(days=-2), amount=Decimal("3"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), state=CheckoutState.objects.fail, retry_count=99, ) ObjectPaymentPlanInstalmentFactory( count=4, due=today + relativedelta(days=-2), amount=Decimal("4"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), state=CheckoutState.objects.fail, retry_count=2, ) qs = ObjectPaymentPlanInstalment.objects.due.order_by("amount") result = [p.amount for p in qs] assert [Decimal("1"), Decimal("2"), Decimal("4")] == result
[docs]@pytest.mark.django_db def test_due_plan_deleted(): today = date.today() ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) object_payment_plan = ObjectPaymentPlanFactory( deleted=True, content_object=SalesLedgerFactory() ) ObjectPaymentPlanInstalmentFactory( object_payment_plan=object_payment_plan, due=today + relativedelta(days=2), amount=Decimal("2"), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-3), amount=Decimal("3"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] assert [Decimal("1"), Decimal("3")] == result
[docs]@pytest.mark.django_db def test_due_plan_deposit(): today = date.today() ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( deposit=True, due=today + relativedelta(days=-2), amount=Decimal("2"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-3), amount=Decimal("3"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] assert [Decimal("1"), Decimal("3")] == result
[docs]@pytest.mark.django_db def test_due_not_due(): today = date.today() ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=1), amount=Decimal("2"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-3), amount=Decimal("3"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] assert [Decimal("1"), Decimal("3")] == result
[docs]@pytest.mark.django_db def test_due_not_pending(): today = date.today() ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-2), state=CheckoutState.objects.fail, retry_count=99, amount=Decimal("2"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-3), amount=Decimal("3"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] assert [Decimal("1"), Decimal("3")] == result
[docs]@pytest.mark.django_db def test_due_within_date_range(): """We must only retry payments which are within x days of the due date.""" today = date.today() for count in range(10): ObjectPaymentPlanInstalmentFactory( count=count, due=today + relativedelta(days=-count), amount=Decimal(count), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) result = [p.amount for p in ObjectPaymentPlanInstalment.objects.due] result.sort() assert [ Decimal("0"), Decimal("1"), Decimal("2"), Decimal("3"), Decimal("4"), ] == result
[docs]@pytest.mark.django_db def test_factory(): ObjectPaymentPlanInstalmentFactory( object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) )
[docs]@pytest.mark.django_db @pytest.mark.parametrize( "deposit_due_date", [date(2015, 3, 10), date(2015, 3, 1), date(2015, 2, 10)] ) def test_create_instalments_first_of_month(deposit_due_date): """Test create instalments. .. note:: The instalment dates are calculated from ``now`` *not* from the deposit due date: https://www.kbsoftware.co.uk/crm/ticket/3604/ """ obj = ObjectPaymentPlanInstalmentFactory( amount=Decimal("50"), count=1, deposit=True, due=deposit_due_date, object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) with freeze_time("2015-03-10"): obj.object_payment_plan.create_instalments() # deposit assert ( deposit_due_date == ObjectPaymentPlanInstalment.objects.get(count=1).due ) # instalment 1 assert ( date(2015, 4, 1) == ObjectPaymentPlanInstalment.objects.get(count=2).due ) # instalment 2 assert ( date(2015, 5, 1) == ObjectPaymentPlanInstalment.objects.get(count=3).due )
[docs]@pytest.mark.django_db @pytest.mark.parametrize( "deposit_due_date", [date(2015, 3, 17), date(2015, 3, 1), date(2015, 2, 10)] ) def test_create_instalments_first_of_month_after_15th(deposit_due_date): """Test create instalments. .. note:: The instalment dates are calculated from ``now`` *not* from the deposit due date: https://www.kbsoftware.co.uk/crm/ticket/3604/ """ obj = ObjectPaymentPlanInstalmentFactory( amount=Decimal("50"), count=1, deposit=True, due=deposit_due_date, object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) with freeze_time("2015-03-17"): obj.object_payment_plan.create_instalments() # deposit assert ( deposit_due_date == ObjectPaymentPlanInstalment.objects.get(count=1).due ) # instalment 1 assert ( date(2015, 5, 1) == ObjectPaymentPlanInstalment.objects.get(count=2).due ) # instalment 2 assert ( date(2015, 6, 1) == ObjectPaymentPlanInstalment.objects.get(count=3).due )
[docs]@pytest.mark.django_db def test_reminder(): """Automated Payment Reminder. 1. I think I need to get ``outstanding_payment_plans`` (``ObjectPaymentPlanManager``) This doesn't seem to worry about any dates. 2. We can check the mail tables to see if we have already reminded the user this month. 3. It would be good if the task could be run every day, but to do that I will need to check to see if the payment is due within the next 7 days. I can do that by checking the ``due`` field. 4. I need to make sure we don't include deposit records in this list. https://www.kbsoftware.co.uk/crm/ticket/3085/ """ today = date.today() ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=5), amount=Decimal("2"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-3), amount=Decimal("3"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) result = [x.amount for x in ObjectPaymentPlanInstalment.objects.reminder()] assert [Decimal("2")] == result
[docs]@pytest.mark.django_db def test_reminder_emails(): today = date.today() contact_1 = ContactFactory( user=UserFactory( email="one@pkimber.net", first_name="Patrick", last_name="K" ) ) contact_2 = ContactFactory(user=UserFactory(email="two@pkimber.net")) contact_3 = ContactFactory(user=UserFactory(email="three@pkimber.net")) contact_4 = ContactFactory(user=UserFactory(email="four@pkimber.net")) sales_ledger_1 = SalesLedgerFactory(contact=contact_1) sales_ledger_2 = SalesLedgerFactory(contact=contact_2) sales_ledger_3 = SalesLedgerFactory(contact=contact_3) sales_ledger_4 = SalesLedgerFactory(contact=contact_4) template = MailTemplateFactory(slug=Customer.MAIL_TEMPLATE_REMINDER) message = MessageFactory(content_object=sales_ledger_2, template=template) MailFactory(email="two@pkimber.net", message=message) instalment_1_due = today + relativedelta(days=4) instalment_1 = ObjectPaymentPlanInstalmentFactory( due=instalment_1_due, amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=sales_ledger_1 ), ) # instalment 2 is not included because an email has already been sent ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=5), amount=Decimal("2"), object_payment_plan=ObjectPaymentPlanFactory( content_object=sales_ledger_2 ), ) # instalment 3 object_payment_plan_3 = ObjectPaymentPlanFactory( content_object=sales_ledger_3 ) instalment_3 = ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=5), amount=Decimal("3"), object_payment_plan=object_payment_plan_3, ) # check the method selects the first instalment i.e. ``instalment_3``. ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=6), amount=Decimal("3.1"), object_payment_plan=object_payment_plan_3, ) # instalment 4 is due in 8 days time, so won't be included ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=8), amount=Decimal("4"), object_payment_plan=ObjectPaymentPlanFactory( content_object=sales_ledger_4 ), ) assert { "one@pkimber.net": instalment_1.pk, "three@pkimber.net": instalment_3.pk, } == ObjectPaymentPlanInstalment.objects.reminder_emails()
[docs]@pytest.mark.django_db def test_send_payment_reminder_emails(): today = date.today() contact_1 = ContactFactory( user=UserFactory(email="a@pkimber.net", first_name="A", last_name="B") ) contact_2 = ContactFactory( user=UserFactory(email="x@pkimber.net", first_name="X", last_name="Y") ) sales_ledger_1 = SalesLedgerFactory(contact=contact_1) sales_ledger_2 = SalesLedgerFactory(contact=contact_2) MailTemplateFactory(slug=Customer.MAIL_TEMPLATE_REMINDER) instalment_1_due = today + relativedelta(days=4) instalment_1 = ObjectPaymentPlanInstalmentFactory( due=instalment_1_due, amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=sales_ledger_1 ), ) instalment_2_due = today + relativedelta(days=5) object_payment_plan_2 = ObjectPaymentPlanFactory( content_object=sales_ledger_2 ) instalment_2 = ObjectPaymentPlanInstalmentFactory( due=instalment_2_due, amount=Decimal("2"), object_payment_plan=object_payment_plan_2, ) ObjectPaymentPlanInstalment.objects.send_payment_reminder_emails() assert 2 == Message.objects.count() # instalment_1 message = Message.objects.for_content_object(instalment_1) assert 1 == message.mail_set.count() mail = message.mail_set.first() assert 2 == mail.mailfield_set.count() assert {"name": "A B", "due": instalment_1_due.strftime("%a %d %b %Y")} == { x.key: x.value for x in mail.mailfield_set.all() } # instalment_2 message = Message.objects.for_content_object(instalment_2) assert 1 == message.mail_set.count() mail = message.mail_set.first() assert 2 == mail.mailfield_set.count() assert {"name": "X Y", "due": instalment_2_due.strftime("%a %d %b %Y")} == { x.key: x.value for x in mail.mailfield_set.all() }
[docs]@pytest.mark.django_db def test_str(): str( ObjectPaymentPlanInstalmentFactory( object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ) ) )