def check(info_date, current_amount, month_pay):
     assert get_credit_info(info_date, **credit_config) == Credit(
         get_date(credit_config["start_date"]), get_date(credit_config["end_date"]),
         Decimal(credit_config["amount"]), Decimal(current_amount),
         Decimal(credit_config["interest"]), None if month_pay is None else Decimal(month_pay),
         _calculate(credit_config["start_date"], credit_config["end_date"],
             credit_config["amount"], credit_config["interest"], credit_config["payments"]))
Example #2
0
def test_iter_months_from_year_to_year():
    assert list(_iter_months("15.11.2013", "15.02.2014")) == [
        get_date("15.11.2013"),
        get_date("15.12.2013"),
        get_date("15.01.2014"),
        get_date("15.02.2014")
    ]
def get_credit_info(info_date,
                    start_date,
                    end_date,
                    amount,
                    interest,
                    payments={}):
    info_date = get_date(info_date)
    start_date = get_date(start_date)
    end_date = get_date(end_date)
    amount = Decimal(amount)
    interest = Decimal(interest)

    payment_schedule = _calculate(start_date, end_date, amount, interest,
                                  payments)

    month_pay = None

    if info_date <= end_date:
        prev_date = start_date
        current_amount = amount

        for payment in payment_schedule:
            if not (payment.date <= info_date or prev_date < info_date):
                break

            if payment.date <= info_date:
                current_amount = payment.credit

            month_pay = payment.month_pay
            prev_date = payment.date
    else:
        current_amount = 0

    return Credit(start_date, end_date, amount, current_amount, interest,
                  month_pay, payment_schedule)
def _calculate(start_date, end_date, credit, interest, payments={}):
    start_date = get_date(start_date)
    end_date = get_date(end_date)
    credit = Decimal(credit)

    payments = {get_date(date): Decimal(payment) for date, payment in payments.items()}

    schedule = []
    prev_date = start_date
    cur_month_pay = month_pay = None
    for date, month_interest in _iter_month_interest(start_date, end_date, interest):
        if month_pay is None or cur_month_pay != month_pay:
            month_pay = _get_month_pay(prev_date, end_date, credit, interest)

        cur_month_pay = payments.pop(date, month_pay)
        if cur_month_pay < month_pay:
            raise InvalidPaymentError("Invalid payment for {}.", format_date(date))

        interest_pay = _round_payment(credit * month_interest)
        credit_pay = cur_month_pay - interest_pay
        credit -= credit_pay

        schedule.append(Payment(date, credit_pay, interest_pay, cur_month_pay, credit))

        prev_date = date

    if payments:
        raise InvalidPaymentDateError("Invalid payment date: {}.", format_date(payments.popitem()[0]))

    if credit:
        payment = schedule[-1]
        schedule[-1] = Payment(payment.date, payment.credit_pay + credit, interest_pay, payment.month_pay + credit, 0)

    return schedule
def get_credit_info(info_date, start_date, end_date, amount, interest, payments={}):
    info_date = get_date(info_date)
    start_date = get_date(start_date)
    end_date = get_date(end_date)
    amount = Decimal(amount)
    interest = Decimal(interest)

    payment_schedule = _calculate(start_date, end_date, amount, interest, payments)

    month_pay = None

    if info_date <= end_date:
        prev_date = start_date
        current_amount = amount

        for payment in payment_schedule:
            if not (payment.date <= info_date or prev_date < info_date):
                break

            if payment.date <= info_date:
                current_amount = payment.credit

            month_pay = payment.month_pay
            prev_date = payment.date
    else:
        current_amount = 0

    return Credit(start_date, end_date, amount, current_amount, interest, month_pay, payment_schedule)
Example #6
0
def test_iter_months_with_non_existing_days_in_months():
    assert list(_iter_months("31.12.2012", "30.04.2013")) == [
        get_date("31.12.2012"),
        get_date("31.01.2013"),
        get_date("28.02.2013"),
        get_date("31.03.2013"),
        get_date("30.04.2013")
    ]
Example #7
0
 def check(info_date, current_amount, month_pay):
     assert get_credit_info(info_date, **credit_config) == Credit(
         get_date(credit_config["start_date"]),
         get_date(credit_config["end_date"]),
         Decimal(credit_config["amount"]), Decimal(current_amount),
         Decimal(credit_config["interest"]),
         None if month_pay is None else Decimal(month_pay),
         _calculate(credit_config["start_date"], credit_config["end_date"],
                    credit_config["amount"], credit_config["interest"],
                    credit_config["payments"]))
def _calculate(start_date, end_date, credit, interest, payments={}):
    start_date = get_date(start_date)
    end_date = get_date(end_date)
    credit = Decimal(credit)

    payments = {
        get_date(date): Decimal(payment)
        for date, payment in payments.items()
    }

    schedule = []
    prev_date = start_date
    cur_month_pay = month_pay = None
    for date, month_interest in _iter_month_interest(start_date, end_date,
                                                     interest):
        if month_pay is None or cur_month_pay != month_pay:
            month_pay = _get_month_pay(prev_date, end_date, credit, interest)

        cur_month_pay = payments.pop(date, month_pay)
        if cur_month_pay < month_pay:
            raise InvalidPaymentError("Invalid payment for {}.",
                                      format_date(date))

        interest_pay = _round_payment(credit * month_interest)
        credit_pay = cur_month_pay - interest_pay
        credit -= credit_pay

        schedule.append(
            Payment(date, credit_pay, interest_pay, cur_month_pay, credit))

        prev_date = date

    if payments:
        raise InvalidPaymentDateError("Invalid payment date: {}.",
                                      format_date(payments.popitem()[0]))

    if credit:
        payment = schedule[-1]
        schedule[-1] = Payment(payment.date, payment.credit_pay + credit,
                               interest_pay, payment.month_pay + credit, 0)

    return schedule
def _iter_months(start_date_string, end_date_string):
    date = get_date(start_date_string)
    end_date = get_date(end_date_string)
    start_day = date.day

    yield date

    while date != end_date:
        if date > end_date:
            raise InvalidDateRangeError(start_date_string, end_date_string)

        if date.month == 12:
            year = date.year + 1
            month = 1
        else:
            year = date.year
            month = date.month + 1

        date = _nearest_valid_date(year, month, start_day)

        yield date
def _iter_months(start_date_string, end_date_string):
    date = get_date(start_date_string)
    end_date = get_date(end_date_string)
    start_day = date.day

    yield date

    while date != end_date:
        if date > end_date:
            raise InvalidDateRangeError(start_date_string, end_date_string)

        if date.month == 12:
            year = date.year + 1
            month = 1
        else:
            year = date.year
            month = date.month + 1

        date = _nearest_valid_date(year, month, start_day)

        yield date
def _check_payment(payment, date, credit_pay, interest_pay, month_pay, overall_precision="0.01"):
    def check(payment, right_payment, precision):
        right_payment = Decimal(right_payment)
        assert right_payment - precision <= payment <= right_payment + precision

    exact_precision = Decimal("0.01")
    overall_precision = Decimal(overall_precision)

    assert payment.date == get_date(date)
    check(payment.credit_pay, credit_pay, overall_precision)
    check(payment.interest_pay, interest_pay, exact_precision)
    check(payment.credit_pay + payment.interest_pay, month_pay, overall_precision)
    check(payment.month_pay, month_pay, overall_precision)
Example #12
0
def _check_payment(payment,
                   date,
                   credit_pay,
                   interest_pay,
                   month_pay,
                   overall_precision="0.01"):
    def check(payment, right_payment, precision):
        right_payment = Decimal(right_payment)
        assert right_payment - precision <= payment <= right_payment + precision

    exact_precision = Decimal("0.01")
    overall_precision = Decimal(overall_precision)

    assert payment.date == get_date(date)
    check(payment.credit_pay, credit_pay, overall_precision)
    check(payment.interest_pay, interest_pay, exact_precision)
    check(payment.credit_pay + payment.interest_pay, month_pay,
          overall_precision)
    check(payment.month_pay, month_pay, overall_precision)
def test_iter_months_from_year_to_year():
    assert list(_iter_months("15.11.2013", "15.02.2014")) == [
        get_date("15.11.2013"), get_date("15.12.2013"),
        get_date("15.01.2014"), get_date("15.02.2014") ]
def test_get_date():
    date = Date(2013, 3, 13)
    assert get_date(date) is date
def test_iter_months_simple():
    assert list(_iter_months("15.03.2013", "15.05.2013")) == [
        get_date("15.03.2013"), get_date("15.04.2013"), get_date("15.05.2013") ]
def test_get_date_invalid():
    with pytest.raises(InvalidDateError):
        get_date("31.02.2013")
Example #17
0
def test_iter_months_simple():
    assert list(_iter_months("15.03.2013", "15.05.2013")) == [
        get_date("15.03.2013"),
        get_date("15.04.2013"),
        get_date("15.05.2013")
    ]
def test_get_date_invalid():
    with pytest.raises(InvalidDateError):
        get_date("31.02.2013")
def test_get_date_from_string():
    assert get_date("13.03.2013") == Date(2013, 3, 13)
def test_iter_months_with_non_existing_days_in_months():
    assert list(_iter_months("31.12.2012", "30.04.2013")) == [
        get_date("31.12.2012"), get_date("31.01.2013"),
        get_date("28.02.2013"), get_date("31.03.2013"),
        get_date("30.04.2013") ]
def test_get_date():
    date = Date(2013, 3, 13)
    assert get_date(date) is date
def test_get_date_from_string():
    assert get_date("13.03.2013") == Date(2013, 3, 13)