def test_save_in_use():
    obj = PaymentPlanFactory()
    ObjectPaymentPlanFactory(
        payment_plan=obj,
        content_object=ContactFactory(),
    )
    obj.name = 'Another Name'
    with pytest.raises(CheckoutError) as e:
        obj.save()
    assert 'Payment plan in use.  Cannot be updated.' in str(e.value)
def test_example():
    plan = PaymentPlanFactory(
        deposit=50,
        count=2,
        interval=1
    )
    deposit_due_date = date(2015, 1, 2)
    result = [
        item[1] for item in plan.example(deposit_due_date, Decimal('100'))
    ]
    assert [Decimal('50'), Decimal('25'), Decimal('25')] == result
def test_simple():
    plan = PaymentPlanFactory(
        deposit=20,
        count=2,
        interval=1
    )
    total = Decimal('100')
    # deposit
    assert Decimal('20') == plan.deposit_amount(total)
    # instalments
    deposit_due_date = date(2015, 1, 2)
    result = plan.instalments(deposit_due_date, total)
    assert [
        (deposit_due_date + relativedelta(months=+1, day=1), Decimal('40')),
        (deposit_due_date + relativedelta(months=+2, day=1), Decimal('40')),
    ] == result
def test_illustration_awkward():
    plan = PaymentPlanFactory(
        deposit=50,
        count=3,
        interval=2
    )
    total = Decimal('200')
    # deposit
    assert Decimal('100') == plan.deposit_amount(total)
    # instalments
    deposit_due_date = date(2015, 1, 2)
    result = plan.instalments(deposit_due_date, total)
    assert [
        (deposit_due_date + relativedelta(months=+2, day=1), Decimal('33.33')),
        (deposit_due_date + relativedelta(months=+4, day=1), Decimal('33.33')),
        (deposit_due_date + relativedelta(months=+6, day=1), Decimal('33.34')),
    ] == result
def test_save_not_in_use():
    ObjectPaymentPlanFactory(
        payment_plan=PaymentPlanFactory(),
        content_object=ContactFactory(),
    )
    obj = PaymentPlanFactory()
    obj.name = 'Another Name'
    obj.save()
    obj.refresh_from_db()
    assert obj.name == 'Another Name'
def test_illustration_typical():
    plan = PaymentPlanFactory(
        deposit=15,
        count=6,
        interval=1
    )
    total = Decimal('600')
    # deposit
    assert Decimal('90') == plan.deposit_amount(total)
    # instalments
    deposit_due_date = date(2015, 1, 22)
    result = plan.instalments(deposit_due_date, total)
    assert [
        (deposit_due_date + relativedelta(months=+2, day=1), Decimal('85')),
        (deposit_due_date + relativedelta(months=+3, day=1), Decimal('85')),
        (deposit_due_date + relativedelta(months=+4, day=1), Decimal('85')),
        (deposit_due_date + relativedelta(months=+5, day=1), Decimal('85')),
        (deposit_due_date + relativedelta(months=+6, day=1), Decimal('85')),
        (deposit_due_date + relativedelta(months=+7, day=1), Decimal('85')),
    ] == result
def test_create_object_payment_plan():
    contact = ContactFactory()
    payment_plan = PaymentPlanFactory(
        deposit=20,
        count=2,
        interval=1,
    )
    # create the contact plan with the deposit
    with transaction.atomic():
        # this must be run within a transaction
        ObjectPaymentPlan.objects.create_object_payment_plan(
            contact,
            payment_plan,
            Decimal('100')
        )
    object_payment_plan = ObjectPaymentPlan.objects.for_content_object(contact)
    # check deposit - count should be '1' and the 'due' date ``today``
    result = [
        (p.count, p.amount, p.due) for p in object_payment_plan.payments
    ]
    assert [(1, Decimal('20'), date.today())] == result
    # create the instalments
    with transaction.atomic():
        # this must be run within a transaction
        object_payment_plan.create_instalments()
    result = [
        (p.count, p.amount, p.due) for p in object_payment_plan.payments
    ]
    offset = 0
    # instalments start a month later if after the 15th of the month
    if date.today().day > 15:
        offset = 1
    assert [
        (
            1,
            Decimal('20'),
            date.today()
        ),
        (
            2,
            Decimal('40'),
            date.today() + relativedelta(months=+(1+offset), day=1)
        ),
        (
            3,
            Decimal('40'),
            date.today() + relativedelta(months=+(2+offset), day=1)
        ),
    ] == result
def test_create_instalments_once_only():
    contact = ContactFactory()
    payment_plan = PaymentPlanFactory(deposit=20, count=2, interval=1)
    # create the contact plan with the deposit
    with transaction.atomic():
        # this must be run within a transaction
        contact_pp = ObjectPaymentPlan.objects.create_object_payment_plan(
            contact,
            payment_plan,
            Decimal('100')
        )
    # create the instalments
    with transaction.atomic():
        # this must be run within a transaction
        contact_pp.create_instalments()
    with pytest.raises(CheckoutError) as e:
        contact_pp.create_instalments()
    assert 'instalments already created' in str(e.value)
def test_interval_greater_zero():
    obj = PaymentPlanFactory(deposit=10, count=6, interval=0)
    with pytest.raises(ValidationError):
        obj.full_clean()
def test_factory():
    PaymentPlanFactory()
def test_save():
    obj = PaymentPlanFactory()
    obj.name = 'Another Name'
    obj.save()
    obj.refresh_from_db()
    assert obj.name == 'Another Name'