import { useRouter } from 'next/navigation';
import React from 'react';
import {
Button,
Card,
Col,
Form,
InputGroup,
Row,
Table,
} from 'react-bootstrap';
import axios from '/api/axios';
import Alerts from '/components/common/Alerts';
import Header from '/components/common/Header';
import Loading from '/components/common/Loading';
import FormInputGroup from '/components/form/FormInputGroup';
import FormWizard from '/components/form/FormWizard';
import BorrowerGiveLoanForm from './BorrowerGiveLoanForm';
import SuretyGiveLoanForm from './SuretyGiveLoanForm';
import CorporateGiveLoanForm from './CorporateGiveLoanForm';
import { NewGiveLoanCreate } from '@/api/new-give-loan';
const CreateGiveLoan = () => {
const router = useRouter();
const [alerts, SetAlerts] = React.useState({
error: [],
success: [],
});
const [errorFields, SetErrorFields] = React.useState([]);
const [isLoading, SetIsLoading] = React.useState(false);
const [selectedBorrowerNo, SetSelectedBorrowerNo] = React.useState(0);
const [leftView, SetLeftView] = React.useState('');
const [isInterviewDetailListVisible, SetIsInterviewDetailListVisible] = React.useState(false);
const [paymentSchedules, SetPaymentSchedules] = React.useState([]);
const [eir, SetEIR] = React.useState('');
const [irr, SetIRR] = React.useState('');
const formRef = React.createRef();
const inputRefs = {};
const separatorEl =
;
// const [paymentFrequency, SetPaymentFrequency] = React.useState(0);
React.useEffect(() => {
if (leftView == 'interview') {
} else if (leftView == 'un-search') {
OpenGoogleTab();
}
}, [leftView]);
const paymentDivisors = {
'annually': 1, //In years
'bi-weekly': (365 / 14), //In years
'daily': 365, //In years
'monthly': 12, //In years
'weekly': (365 / 7), //In years
'payday': 365, //In years
'quarterly': 4, //In years
'semi-annually': 2, //In years
};
const CalculateEIR = (flows, paymentFrequency) => {
};
const CalculatePaymentSchedule = (e) => {
setTimeout(() => { // set timeout to let the state updated
if (
!inputRefs.disbursement1_amount?.current ||
!inputRefs.disbursement1_installment_count?.current ||
!inputRefs.disbursement1_payment_frequency_id?.current ||
!inputRefs.loan_plan1_interest_calculation_method_id?.current ||
!inputRefs.loan_plan1_interest_frequency_id?.current ||
!inputRefs.loan_plan1_interest_rate?.current ||
inputRefs.disbursement1_installment_count.current.value == 0 ||
!parseInt(inputRefs.disbursement1_payment_frequency_id?.current?.props?.value?.value) ||
!parseInt(inputRefs.loan_plan1_interest_rate.current.value)
) return;
const amount = inputRefs.disbursement1_amount.current.value;
const installments = inputRefs.disbursement1_installment_count.current.value;
let interestRate = inputRefs.loan_plan1_interest_rate.current.value;
const paymentFrequencyLabel = inputRefs.disbursement1_payment_frequency_id.current.props.value.label;
const interestFrequencyLabel = inputRefs.loan_plan1_interest_frequency_id.current.props?.value?.label;
let interestCalculationMethod = inputRefs.loan_plan1_interest_calculation_method_id.current.props?.value?.label;
if (interestCalculationMethod == 'Reducing Interest') interestCalculationMethod = 'Compound Interest';
const biweeklyCalculationMethod = 'custom';// "";
const disbursement1FirstPaymentDate = new Date(inputRefs.disbursement1_first_payment_date?.current?.value);
const paymentFrequency = GetPaymentFrequency();
const interestFrequency = interestFrequencyLabel == 'payday' ? 1 : (1 / paymentDivisors[interestFrequencyLabel]);
const termInterest = amount * interestRate / 100; //Generally Annual Interest. If Principal = 5000, R = 10% monthly then I = Rs.500 monthly
if (interestRate == 0) interestCalculationMethod = 'Simple Interest'; // for 0% loans - to divide the amount equally among installments
let totalInterest = (termInterest * paymentFrequency * installments / interestFrequency); // 500 * 1(yearly) / (1/12) = 12000
if (paymentFrequencyLabel == 'payday') {
const paydayDays = (disbursement1FirstPaymentDate.getTime() - (new Date(inputRefs.application1_date.current.value)).getTime()) / 86400000;
totalInterest *= paydayDays;
}
const emiInterest = totalInterest / installments;
const tmpPaymentSchedules = [];
//Final variables to be used
if (interestCalculationMethod != "Compound Interest" || paymentFrequencyLabel == "payday") {
let principal = 0;
let lastPrincipal = amount;
if (interestCalculationMethod != "Rest Schedule") {
principal = Math.round(amount / installments * 100) / 100;
const principalAdjustAdd = Math.round((amount - principal * installments) * 100) / 100;
lastPrincipal = Math.round((principal + principalAdjustAdd) * 100) / 100;
}
const interest = Math.round(emiInterest * 100) / 100;
const interestAdjustAdd = Math.round((totalInterest - interest * installments) * 100) / 100;
const lastInterest = Math.round((interest + interestAdjustAdd) * 100) / 100;
// Generate the payment schedule TRs
// todo - this code is copied below too, make it a function
for (let i = 0; i < installments; i++) {
tmpPaymentSchedules.push({
interest: interest,
principal: principal,
});
}
//Adjustment to round off last value to get accurate totals
if (tmpPaymentSchedules.length > 0) {
tmpPaymentSchedules[tmpPaymentSchedules.length - 1] = {
interest: lastInterest,
principal: lastPrincipal,
};
}
} else {
//this is actually reducing interest and not compound interest
const proRatedInterestRate = interestRate * (1 / interestFrequency) * paymentFrequency;
//needed when pay and int freqs are different. If they are same this wont do anything.
interestRate = proRatedInterestRate;
const annuity = (1 - 1 / (Math.pow((1 + interestRate / 100), installments))) / (interestRate / 100);
//this below is the installment amount
var compoundInstallment = Math.round(amount / annuity * 100) / 100;
let osPrincipal = amount;
// Generate the payment schedule data
for (let i = 0; i < installments; i++) {
const compoundInterest = Math.round(osPrincipal * interestRate / 100 * 100) / 100;
let compoundPrincipal = Math.round((compoundInstallment - compoundInterest) * 100) / 100;
osPrincipal -= compoundPrincipal;
// last installment
if (i == installments - 1) compoundPrincipal = Math.round((compoundPrincipal + osPrincipal) * 100) / 100;
tmpPaymentSchedules.push({
interest: compoundInterest,
principal: compoundPrincipal,
});
}
}
if (disbursement1FirstPaymentDate) {
let dateObject = disbursement1FirstPaymentDate;
let disbursement1SecondPaymentDate = new Date(inputRefs.disbursement1_second_payment_date?.current?.value);
if (!inputRefs.disbursement1_second_payment_date?.current.value) {
disbursement1SecondPaymentDate = new Date(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate() + 15);
if (inputRefs.disbursement1_second_payment_date?.current) inputRefs.disbursement1_second_payment_date.current.value = (
disbursement1SecondPaymentDate.getFullYear() + '-' +
(disbursement1SecondPaymentDate.getMonth() + 1) + '-' +
disbursement1SecondPaymentDate.getDate()
);
}
for (let i = 0; i < installments; i++) {
if (i % 2 != 0 && paymentFrequencyLabel == 'bi-weekly' && biweeklyCalculationMethod == 'automatic') dateObject = new Date(disbursement1SecondPaymentDate.getFullYear, disbursement1SecondPaymentDate.getMonth(), disbursement1SecondPaymentDate.getDate());
else dateObject = new Date(disbursement1FirstPaymentDate.getFullYear(), disbursement1FirstPaymentDate.getMonth(), disbursement1FirstPaymentDate.getDate());
if (paymentFrequencyLabel == 'monthly') {
dateObject.setMonth(dateObject.getMonth() + i);
const dateObject2 = new Date(disbursement1FirstPaymentDate.getFullYear(), disbursement1FirstPaymentDate.getMonth() + 1, 1);
dateObject2.setMonth(dateObject2.getMonth() + i);
if (dateObject.getMonth() > dateObject2.getMonth()) dateObject = new Date(dateObject.getFullYear(), dateObject.getMonth(), 0); // check if next month jumps one more month. Then adjust the next month due date; Move 1 month back and get the last day of the month
}
else if (paymentFrequencyLabel == 'daily') dateObject.setDate(dateObject.getDate() + i);
else if (paymentFrequencyLabel == 'quarterly') dateObject.setMonth(dateObject.getMonth() + i * 3);
else if (paymentFrequencyLabel == 'semi-annually') dateObject.setMonth(dateObject.getMonth() + i * 6);
else if (paymentFrequencyLabel == 'annually') dateObject.setFullYear(dateObject.getFullYear() + i);
else if (paymentFrequencyLabel == 'bi-weekly') {
if (biweeklyCalculationMethod == 'automatic') dateObject.setMonth(dateObject.getMonth() + parseInt(i / 2));
else dateObject.setDate(dateObject.getDate() + i * 14);
}
else if (paymentFrequencyLabel == "weekly") dateObject.setDate(dateObject.getDate() + i * 7);
tmpPaymentSchedules[i]['date'] = dateObject.getFullYear() + '-' + (dateObject.getMonth() + 1).toString().padStart(2, '0') + '-' + dateObject.getDate().toString().padStart(2, '0');
}
}
SetPaymentSchedules(tmpPaymentSchedules);
});
};
const CalculatePaymentScheduleTotal = () => {
// ceck
const flows = [];
flows.push(inputRefs.disbursement1_amount?.curent?.value * -1);
const paymentFrequency = GetPaymentFrequency();
const eirPaymentFrequency = 1 / paymentFrequency;
// Additional Row to show the total
// $total_row = "Total | | Principal | | Interest | | = | |
";
// if(!$("#ps_total_row").length) $($total_row).appendTo($("#payment_schedule1_entry"));
const interests = [];
const principals = [];
let interestTotal = 0;
let principalTotal = 0;
paymentSchedules.map((schedule) => {
const principal = parseFloat(schedule.principal ?? 0);
principalTotal += principal;
principals.push(principal);
const interest = parseFloat(schedule.interest ?? 0);
interestTotal += interest;
interests.push(interest);
flows.push(principal + interest);
});
if (
(inputRefs.disbursement1_amount?.current?.value ?? 0) > 0 &&
(inputRefs.disbursement1_installment_count?.curent?.value ?? 0) > 0
) {
const irr = IRR(flows, 0.1);
//Prashant: commented this on 8-5-3018 as suggested by Marcus. and set to fixed 47%
SetEIR(Math.round((Math.pow((1 + irr), paymentFrequency) - 1) * 10000) / 100);
SetIRR(Math.round(irr * 10000) / 100);
}
SetPaymentSchedules([...paymentSchedules, {
interest: Math.round(interestTotal * 100) / 100,
principal: Math.round(principalTotal * 100) / 100,
type: 'total',
}]);
/*
$("input[name='payment_schedule1_principal[]']").each(function(){
$principalTotal = $principalTotal + parseFloat($(this).val() || 0);
$emi_total = $emi_total + parseFloat($(this).val());
$principals.push($(this).val() || 0);
})
$("input[name='payment_schedule1_interest[]']").each(function(){
$interestTotal = $interestTotal + parseFloat($(this).val() || 0);
$emi_total = $emi_total + parseFloat($(this).val());
$interests.push($(this).val() || 0);
})
$principalTotal = Math.round($principalTotal*100)/100;
$interestTotal = Math.round($interestTotal*100)/100;
$emi_total = Math.round($emi_total*100)/100;
for(var $i = 0; $i < Math.max($principals.length, $interests.length); $i++) $flows.push(parseFloat($principals[$i])+parseFloat($interests[$i]))
calculate_eir($flows, $eirPaymentFrequency);
if($principalTotal) $("#principalTotal").html($principalTotal);
if($interestTotal) $("#interestTotal").html($interestTotal);
if($emi_total) $("#emi_total").html($emi_total);
*/
};
React.useEffect(() => { if (paymentSchedules.length > 0 && paymentSchedules[paymentSchedules.length - 1].type != 'total') { CalculatePaymentScheduleTotal(); } }, [paymentSchedules]); // only call CalculatePaymentScheduleTotal when latest row is not total
const GenerateInput = (inp, i) => {
if (inp != 'SEPARATOR' && !inp.ref) {
const ref = React.createRef();
inp['ref'] = ref;
inputRefs[inp.inputName] = ref;
}
return inp == 'SEPARATOR' ? separatorEl :
};
const GetPaymentFrequency = () => {
if (!parseInt(inputRefs.disbursement1_payment_frequency_id?.current?.props?.value?.value)) return 0;
const paymentFrequencyLabel = inputRefs.disbursement1_payment_frequency_id.current.props.value.label;
if (!paymentDivisors[paymentFrequencyLabel]) return 0;
return 1 / paymentDivisors[paymentFrequencyLabel];
};
// IRR and EIR calculation methods. Referred from http://finance.thinkanddone.com/finding_irr_with_nfv_equation_using_newton_raphson_method.html
const IRR = (flows, seed) => {
const steps = flows.length;
let fx = 0;
let fx1 = 0;
for (let i = 0; i < steps; i++) {
fx += flows[i] * Math.pow((1 + seed), (steps - i));
fx1 += (steps - i) * flows[i] * Math.pow((1 + seed), (steps - i - 1));
}
const distraction = fx / fx1;
let seed1 = seed - distraction;
if (distraction > 0.000001 || distraction < 0) {
if (seed1 < 0) {
seed1 = Math.round(Math.random() * 100) / 100;
return irr(flows, seed1);
}
else return irr(flows, seed1);
}
else return seed;
}
const OpenGoogleTab = () => window.open('https://www.google.com/search?q=');
const currentDateTime = new Date();
const currentDateStr = currentDateTime.getFullYear() + '-' + (currentDateTime.getMonth() + 1).toString().padStart(2, '0') + '-' + currentDateTime.getDate().toString().padStart(2, '0');
/* React.useEffect(() => {
[
['disbursement1_amount', 1000],
['disbursement1_installment_count', 10],
['disbursement1_first_payment_date', '2024-06-30'],
['loan_plan1_interest_rate', 10],
].map((data) => {
if (inputRefs[data[0]]?.current) inputRefs[data[0]].current.value = data[1];
});
}, []); */
const GiveLoanCreateSubmit = async () => {
SetIsLoading(true);
const res = await NewGiveLoanCreate(formRef.current);
console.log(res);
if (res.data?.success) {
} else if (res.response?.status == 422) { // validation error
const formErrors = res.response.data?.errors ?? {};
const formErrorFields = Object.keys(formErrors);
const formErrorMsgs = [];
formErrorFields.map((attr) => {
formErrorMsgs.push(formErrors[attr]);
});
SetAlerts({
error: formErrorMsgs,
success: [],
});
SetErrorFields(formErrorFields);
} else {
SetAlerts({ error: res.response.message ?? 'There was an error while processing the request' })
}
window.scrollTo({ top: 0 });
SetIsLoading(false);
};
return <>
1
{input}
}}
/>
2
3
{input}
}}
/>
>;
};
CreateGiveLoan.layout = "Contentlayout";
export default CreateGiveLoan;