예제 #1
0
	def book_unaccrued_interest(self):
		precision = cint(frappe.db.get_default("currency_precision")) or 2
		if self.total_interest_paid > self.interest_payable:
			if not self.is_term_loan:
				# get last loan interest accrual date
				last_accrual_date = get_last_accrual_date(self.against_loan)

				# get posting date upto which interest has to be accrued
				per_day_interest = flt(get_per_day_interest(self.pending_principal_amount,
					self.rate_of_interest, self.posting_date), 2)

				no_of_days = flt(flt(self.total_interest_paid - self.interest_payable,
					precision)/per_day_interest, 0) - 1

				posting_date = add_days(last_accrual_date, no_of_days)

				# book excess interest paid
				process = process_loan_interest_accrual_for_demand_loans(posting_date=posting_date,
					loan=self.against_loan, accrual_type="Repayment")

				# get loan interest accrual to update paid amount
				lia = frappe.db.get_value('Loan Interest Accrual', {'process_loan_interest_accrual':
					process}, ['name', 'interest_amount', 'payable_principal_amount'], as_dict=1)

				self.append('repayment_details', {
					'loan_interest_accrual': lia.name,
					'paid_interest_amount': flt(self.total_interest_paid - self.interest_payable, precision),
					'paid_principal_amount': 0.0,
					'accrual_type': 'Repayment'
				})
예제 #2
0
    def book_unaccrued_interest(self):
        precision = cint(frappe.db.get_default("currency_precision")) or 2
        if flt(self.total_interest_paid, precision) > flt(
                self.interest_payable, precision):
            if not self.is_term_loan:
                # get last loan interest accrual date
                last_accrual_date = get_last_accrual_date(self.against_loan)

                # get posting date upto which interest has to be accrued
                per_day_interest = get_per_day_interest(
                    self.pending_principal_amount, self.rate_of_interest,
                    self.posting_date)

                no_of_days = (flt(
                    flt(self.total_interest_paid - self.interest_payable,
                        precision) / per_day_interest, 0) - 1)

                posting_date = add_days(last_accrual_date, no_of_days)

                # book excess interest paid
                process = process_loan_interest_accrual_for_demand_loans(
                    posting_date=posting_date,
                    loan=self.against_loan,
                    accrual_type="Repayment")

                # get loan interest accrual to update paid amount
                lia = frappe.db.get_value(
                    "Loan Interest Accrual",
                    {"process_loan_interest_accrual": process},
                    ["name", "interest_amount", "payable_principal_amount"],
                    as_dict=1,
                )

                if lia:
                    self.append(
                        "repayment_details",
                        {
                            "loan_interest_accrual":
                            lia.name,
                            "paid_interest_amount":
                            flt(
                                self.total_interest_paid -
                                self.interest_payable, precision),
                            "paid_principal_amount":
                            0.0,
                            "accrual_type":
                            "Repayment",
                        },
                    )
예제 #3
0
def get_amounts(amounts, against_loan, posting_date):
	precision = cint(frappe.db.get_default("currency_precision")) or 2

	against_loan_doc = frappe.get_doc("Loan", against_loan)
	loan_type_details = frappe.get_doc("Loan Type", against_loan_doc.loan_type)
	accrued_interest_entries = get_accrued_interest_entries(against_loan_doc.name)

	pending_accrual_entries = {}

	total_pending_interest = 0
	penalty_amount = 0
	payable_principal_amount = 0
	final_due_date = ''
	due_date = ''

	for entry in accrued_interest_entries:
		# Loan repayment due date is one day after the loan interest is accrued
		# no of late days are calculated based on loan repayment posting date
		# and if no_of_late days are positive then penalty is levied

		due_date = add_days(entry.posting_date, 1)
		no_of_late_days = date_diff(posting_date,
			add_days(due_date, loan_type_details.grace_period_in_days)) + 1

		if no_of_late_days > 0 and (not against_loan_doc.repay_from_salary) and entry.accrual_type == 'Regular':
			penalty_amount += (entry.interest_amount * (loan_type_details.penalty_interest_rate / 100) * no_of_late_days)

		total_pending_interest += entry.interest_amount
		payable_principal_amount += entry.payable_principal_amount

		pending_accrual_entries.setdefault(entry.name, {
			'interest_amount': flt(entry.interest_amount, precision),
			'payable_principal_amount': flt(entry.payable_principal_amount, precision)
		})

		if due_date and not final_due_date:
			final_due_date = add_days(due_date, loan_type_details.grace_period_in_days)

	if against_loan_doc.status in ('Disbursed', 'Loan Closure Requested', 'Closed'):
		pending_principal_amount = against_loan_doc.total_payment - against_loan_doc.total_principal_paid \
			- against_loan_doc.total_interest_payable - against_loan_doc.written_off_amount
	else:
		pending_principal_amount = against_loan_doc.disbursed_amount - against_loan_doc.total_principal_paid \
			- against_loan_doc.total_interest_payable - against_loan_doc.written_off_amount

	unaccrued_interest = 0
	if due_date:
		pending_days = date_diff(posting_date, due_date) + 1
	else:
		last_accrual_date = get_last_accrual_date(against_loan_doc.name)
		pending_days = date_diff(posting_date, last_accrual_date) + 1

	if pending_days > 0:
		principal_amount = flt(pending_principal_amount, precision)
		per_day_interest = get_per_day_interest(principal_amount, loan_type_details.rate_of_interest, posting_date)
		unaccrued_interest += (pending_days * flt(per_day_interest, precision))

	amounts["pending_principal_amount"] = flt(pending_principal_amount, precision)
	amounts["payable_principal_amount"] = flt(payable_principal_amount, precision)
	amounts["interest_amount"] = flt(total_pending_interest, precision)
	amounts["penalty_amount"] = flt(penalty_amount, precision)
	amounts["payable_amount"] = flt(payable_principal_amount + total_pending_interest + penalty_amount, precision)
	amounts["pending_accrual_entries"] = pending_accrual_entries
	amounts["unaccrued_interest"] = unaccrued_interest

	if final_due_date:
		amounts["due_date"] = final_due_date

	return amounts
예제 #4
0
def get_amounts(amounts, against_loan, posting_date):
    precision = cint(frappe.db.get_default("currency_precision")) or 2

    against_loan_doc = frappe.get_doc("Loan", against_loan)
    loan_type_details = frappe.get_doc("Loan Type", against_loan_doc.loan_type)
    accrued_interest_entries = get_accrued_interest_entries(
        against_loan_doc.name, posting_date)

    computed_penalty_date, pending_penalty_amount = get_penalty_details(
        against_loan)
    pending_accrual_entries = {}

    total_pending_interest = 0
    penalty_amount = 0
    payable_principal_amount = 0
    final_due_date = ""
    due_date = ""

    for entry in accrued_interest_entries:
        # Loan repayment due date is one day after the loan interest is accrued
        # no of late days are calculated based on loan repayment posting date
        # and if no_of_late days are positive then penalty is levied

        due_date = add_days(entry.posting_date, 1)
        due_date_after_grace_period = add_days(
            due_date, loan_type_details.grace_period_in_days)

        # Consider one day after already calculated penalty
        if computed_penalty_date and getdate(
                computed_penalty_date) >= due_date_after_grace_period:
            due_date_after_grace_period = add_days(computed_penalty_date, 1)

        no_of_late_days = date_diff(posting_date,
                                    due_date_after_grace_period) + 1

        if (no_of_late_days > 0 and (not against_loan_doc.repay_from_salary)
                and entry.accrual_type == "Regular"):
            penalty_amount += (
                entry.interest_amount *
                (loan_type_details.penalty_interest_rate / 100) *
                no_of_late_days)

        total_pending_interest += entry.interest_amount
        payable_principal_amount += entry.payable_principal_amount

        pending_accrual_entries.setdefault(
            entry.name,
            {
                "interest_amount":
                flt(entry.interest_amount, precision),
                "payable_principal_amount":
                flt(entry.payable_principal_amount, precision),
            },
        )

        if due_date and not final_due_date:
            final_due_date = add_days(due_date,
                                      loan_type_details.grace_period_in_days)

    pending_principal_amount = get_pending_principal_amount(against_loan_doc)

    unaccrued_interest = 0
    if due_date:
        pending_days = date_diff(posting_date, due_date) + 1
    else:
        last_accrual_date = get_last_accrual_date(against_loan_doc.name)
        pending_days = date_diff(posting_date, last_accrual_date) + 1

    if pending_days > 0:
        principal_amount = flt(pending_principal_amount, precision)
        per_day_interest = get_per_day_interest(
            principal_amount, loan_type_details.rate_of_interest, posting_date)
        unaccrued_interest += pending_days * per_day_interest

    amounts["pending_principal_amount"] = flt(pending_principal_amount,
                                              precision)
    amounts["payable_principal_amount"] = flt(payable_principal_amount,
                                              precision)
    amounts["interest_amount"] = flt(total_pending_interest, precision)
    amounts["penalty_amount"] = flt(penalty_amount + pending_penalty_amount,
                                    precision)
    amounts["payable_amount"] = flt(
        payable_principal_amount + total_pending_interest + penalty_amount,
        precision)
    amounts["pending_accrual_entries"] = pending_accrual_entries
    amounts["unaccrued_interest"] = flt(unaccrued_interest, precision)

    if final_due_date:
        amounts["due_date"] = final_due_date

    return amounts