Files
arif_grafin/CONTENT/ROOT_URI/Admin/Due.php

408 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="">
<div class="text-right mb-3" style="margin-bottom: 15px;">
<button id="downloadPdf" class="btn btn-primary">Download Demand Sheet</button>
</div>
<table class="table table-striped table-bordered table-hover table-responsive">
<tr>
<th>SL</th>
<th>Type</th>
<th>AC No</th>
<th>Name</th>
<th>Mobile</th>
<th>Account Create Date</th>
<th>Maturity Value</th>
<th>Balance</th>
<th>Total EMI</th>
<th>Total Paid EMI</th>
<th>Deu EMI Till Date</th>
<th>EMI Amount</th>
<th>Total Due Amount</th>
</tr>
<?php
// function countCycles($cycle, $createDate, $totalInstallment) {
// $today = new DateTime();
// $startDate = new DateTime($createDate);
// $cycle = strtoupper(trim($cycle)); // normalize input (W/M/D)
// if ($cycle === "D") {
// // For daily cycles, count starts from the next day
// $startDate->modify('+1 day');
// if ($startDate > $today) {
// $count = 0;
// } else {
// $diff = $startDate->diff($today);
// $count = $diff->days;
// }
// } elseif ($cycle === "W") {
// // For weekly cycles, first payment is next week
// $startDate->modify('next monday'); // or use '+1 week' if you want exactly 7 days later
// if ($startDate > $today) {
// $count = 0;
// } else {
// $diff = $startDate->diff($today);
// $count = floor($diff->days / 7);
// }
// } elseif ($cycle === "M") {
// // For monthly cycles, first payment is next month
// $startDate->modify('first day of next month');
// if ($startDate > $today) {
// $count = 0;
// } else {
// $diff = $startDate->diff($today);
// $count = ($diff->y * 12) + $diff->m;
// // If we're in the same month but after the start date, add one
// if ($diff->y == 0 && $diff->m == 0 && $diff->d > 0) {
// $count++;
// }
// }
// } else {
// $count = 0; // unknown cycle
// }
// // Ensure count doesn't exceed total installments
// return min($count, $totalInstallment);
// }
function countCycles($cycle, $createDate, $totalInstallment, $accountType) {
$today = new DateTime();
$startDate = new DateTime($createDate);
$cycle = strtoupper(trim($cycle));
if ($cycle === "D") {
// দৈনিক চক্র: ক্রিয়েশন ডেট থেকেই শুরু
if($accountType === 'Recurring'){
$firstPaymentDate = clone $startDate; // সেই দিনই শুরু
} elseif($accountType === 'Loan') {
$firstPaymentDate = (clone $startDate)->modify('+1 day'); // পরের দিন থেকে
}
if ($firstPaymentDate > $today) {
$count = 0;
} else {
$diff = $firstPaymentDate->diff($today);
$count = $diff->days + 1; // +1 because diff->days doesn't include start day
}
} elseif ($cycle === "W") {
if($accountType === 'Recurring'){
$firstPaymentDate = clone $startDate;
}elseif($accountType === 'Loan'){
// সাপ্তাহিক চক্র: দিন পরে প্রথম EMI
$firstPaymentDate = (clone $startDate)->modify('+7 days');
}
if ($firstPaymentDate > $today) {
$count = 0;
} else {
$diff = $firstPaymentDate->diff($today);
$count = floor($diff->days / 7) + 1;
}
} elseif ($cycle === "M") {
if($accountType === 'Recurring'){
$firstPaymentDate = clone $startDate;
}elseif($accountType === 'Loan'){
// মাসিক চক্র: পরের মাসের同一天 প্রথম EMI
$firstPaymentDate = (clone $startDate)->modify('+1 month');
}
// যদি পরের মাসে同一天 না থাকে (যেমন 31st Jan থেকে 28/29th Feb)
if ($firstPaymentDate->format('d') != $startDate->format('d')) {
$firstPaymentDate->modify('last day of this month');
}
if ($firstPaymentDate > $today) {
$count = 0;
} else {
$count = 1; // প্রথম EMI already due
$nextPaymentDate = clone $firstPaymentDate;
// পরের মাসগুলির জন্য গণনা
while ($nextPaymentDate <= $today) {
$nextPaymentDate->modify('+1 month');
// তারিখ adjust করাが必要 হলে
if ($nextPaymentDate->format('d') != $firstPaymentDate->format('d')) {
$nextPaymentDate->modify('last day of this month');
}
if ($nextPaymentDate <= $today) {
$count++;
}
}
}
} else {
$count = 0;
}
return min($count, $totalInstallment);
}
$conn = new mysqli($GLOBALS['host'], $GLOBALS['user'], $GLOBALS['pass'], $GLOBALS['db']);
if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); }
$totalLoanEMIAmount = 0;
$totalDeuEMITillDate = 0;
$totalRecurringEMIAmount = 0;
$totalDeuInstallTillDate = 0;
$agent_id = $_SESSION['user_id'];
$types = ['Loan', 'Recurring'];
$pdfData = [];
$sl = 1;
// Grand total for PDF
$grandTotal = [
'accounts' => 0,
'paidInstallments' => 0,
'dueInstallments' => 0,
'dueAmount' => 0
];
foreach($types as $type){
$typeLike = "%$type%";
if($_SESSION['type']==='admin'){
$sql = "SELECT * FROM `" . $GLOBALS['arif_ac'] . "` WHERE `AA_TYPE` LIKE ? AND (`STATUS` IS NULL OR (`STATUS`!='closed' AND `STATUS`!='matured')) ORDER BY `AA_ID` DESC";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $typeLike);
} elseif($_SESSION['type']==='agent'){
$sql = "SELECT * FROM `" . $GLOBALS['arif_ac'] . "` WHERE `AA_TYPE` LIKE ? AND (`STATUS` IS NULL OR (`STATUS`!='closed' AND `STATUS`!='matured')) AND `AA_AGENT`=? ORDER BY `AA_ID` DESC";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $typeLike, $agent_id);
}
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows>0){
echo "<tr><td colspan='13' style='text-align:center; font-weight:bold; background:#f0f0f0;'>$type Demand</td></tr>";
while($row = $result->fetch_assoc()){
$totalDueAmt = $row['AA_BAL'];
if ($row['AA_INSTALLMENT'] > 0) {
$paidInst = ($row['AA_MATURE_VALUE'] + $row['AA_BAL']) / $row['AA_INSTALLMENT'];
$paidInst = number_format($paidInst, 2);
$remainInst = abs($row['AA_BAL']) / $row['AA_INSTALLMENT'];
$remainInst = number_format($remainInst, 2);
} else {
$paidInst = 0; // বা অন্য লজিক
$remainInst = 0;
}
if($row['AA_TYPE'] === 'Loan'){
$paidInstallment = ($row['AA_MATURE_VALUE'] + $row['AA_BAL']) / $row['AA_INSTALLMENT'];
$paidInstallment = number_format($paidInstallment, 2, '.', '');
$deuEMITillDate = countCycles($row['AA_ACTYPE'], $row['AA_DATE'], $row['AA_NO_OF_PAYMENT'], $row['AA_TYPE']) - $paidInstallment;
$deuEMITillDate = number_format($deuEMITillDate, 2, '.', '');
if($deuEMITillDate > 0){
// echo $deuEMITillDate;
$totalDeuEMITillDate += $deuEMITillDate; // এখানে যোগ হচ্ছে
$totalLoanEMIAmount += $row['AA_INSTALLMENT'];
}
}elseif($row['AA_TYPE'] === 'Recurring'){
$paidInstallment = $row['AA_BAL'] / $row['AA_INSTALLMENT'];
$paidInstallment = number_format($paidInstallment, 2, '.', '');
$deuEMITillDate = countCycles($row['AA_ACTYPE'], $row['AA_DATE'], $row['AA_NO_OF_PAYMENT'], $row['AA_TYPE']) - $paidInstallment;
// $deuEMITillDate = abs($deuEMITillDate);
$deuEMITillDate = number_format($deuEMITillDate, 2, '.', '');
if($deuEMITillDate > 0){
// echo $deuEMITillDate;
$totalDeuInstallTillDate += $deuEMITillDate; // এখানে যোগ হচ্ছে
$totalRecurringEMIAmount += $row['AA_INSTALLMENT'];
}
}
// HTML table row
if($deuEMITillDate > 0){
echo "<tr>
<td>".$sl."</td>
<td>".$row['AA_ACTYPE'].", ".$row['AA_TYPE']."</td>
<td>".$row['AA_ACNO']."</td>
<td>".$row['AA_NAME']."</td>
<td>".$row['AA_PHONE']."</td>
<td>".$row['AA_DATE']."</td>
<td>".$row['AA_MATURE_VALUE']."</td>
<td>".$row['AA_BAL']."</td>
<td>".$row['AA_NO_OF_PAYMENT']."</td>
<td>".$paidInstallment."</td>
<td>".$deuEMITillDate."</td>
<td>".$row['AA_INSTALLMENT']."</td>
<td>".$totalDueAmt."</td>
</tr>";
}
// <td>".$remainInst."</td> <td>".$row['AA_NO_OF_PAYMENT']."</td>
// PDF simplified row
// "SL","NAME ","MOBILE NO", "CYCLE", "ACCOUNT NO","EMI PAID","EMI DUE", "EMI AMOUNT", "CUSTOMER. SIGN"
if($deuEMITillDate > 0){
$pdfData[] = [
$type,
$sl,
$row['AA_NAME'], // NAME OF ACCOUNT HOLDER
$row['AA_PHONE'], // MOBILE NO (blank)
$row['AA_ACTYPE'], // EMI Cycle
$row['AA_ACNO'], // ACCOUNT NO
$paidInstallment, // NO OF INSTALLMENT PAID
$deuEMITillDate, // NO OF INSTALLMENT DUE
$row['AA_INSTALLMENT'], // EMI AMOUNT
// $totalDueAmt, // TOTAL DUE AMOUNT
"" // CUSTOMER SIGNATURE
];
}
// Update grand total
$grandTotal['accounts']++;
$grandTotal['paidInstallments'] += $paidInstallment;
$grandTotal['dueInstallments'] += $deuEMITillDate;
$grandTotal['dueAmount'] += $totalDueAmt;
$sl++;
// echo $dueInst . '<br>';
}
}
}
$conn->close();
$grandTotal['totalNumberOfLoanEMI'] = $totalDeuEMITillDate;
$grandTotal['totalNumberOfRecurringEMI'] = $totalDeuInstallTillDate;
$grandTotal['totalLoanEMIAmount'] = $totalLoanEMIAmount;
$grandTotal['totalRecurringEMIAmount'] = $totalRecurringEMIAmount;
// echo "<br>Total Due EMI Till Date (Loan): ".$totalDeuEMITillDate;
// echo "<br>Total Due Installment Till Date (Recurring): ".$totalDeuInstallTillDate;
?>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.28/jspdf.plugin.autotable.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('downloadPdf').addEventListener('click', function() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF('p', 'pt', 'a4');
const userType = "<?php echo $_SESSION['type']; ?>";
const userName = "<?php echo $_SESSION['name']; ?>";
const now = new Date();
const dateTime = now.toLocaleDateString() + " " + now.toLocaleTimeString();
const titleText = "Grafin Ventures Demand Sheet";
const pdfData = <?php echo json_encode($pdfData); ?>;
const grandTotal = <?php echo json_encode($grandTotal); ?>;
const logo = new Image();
logo.src = '/asset/images/new_logo2.jpg';
logo.onload = () => addHeader();
logo.onerror = () => addHeader();
function addHeader(){
try { doc.addImage(logo, 'PNG', 40, 30, 40, 40); } catch(e) {}
doc.setFontSize(16);
doc.text(titleText, 100, 50);
doc.setFontSize(10);
doc.text(`Generated on: ${dateTime}`, 40, 80);
doc.text(`User Type: ${userType}`, 40, 95);
doc.text(`Agen Name: ${userName}`, 40, 110);
let y = 130;
const headers = ["SL","NAME ","MOBILE NO", "CYCLE", "ACCOUNT NO","EMI PAID","EMI DUE", "EMI AMOUNT", "CUSTOMER. SIGN"];
let currentType = '';
let rows = [];
pdfData.forEach(row=>{
if(row[0] !== currentType){
if(rows.length>0){
doc.autoTable({
head:[headers],
body:rows,
startY:y,
styles:{
fontSize:7,
cellPadding:3,
lineWidth: 0.1, // border width
lineColor: [0, 0, 0] // black border color
},
headStyles:{ fillColor: false, textColor: 0 },
bodyStyles:{ valign:'middle', fillColor: false },
alternateRowStyles: { fillColor: false },
columnStyles: { 1: { cellWidth: 110 } }
});
y = doc.lastAutoTable.finalY + 10;
rows=[];
}
currentType = row[0];
doc.setFont(undefined,'bold');
doc.text(`${currentType} Demand`,40,y);
y+=15;
doc.setFont(undefined,'normal');
}
rows.push(row.slice(1));
});
if(rows.length>0){
doc.autoTable({
head:[headers],
body:rows,
startY:y,
styles:{
fontSize:7,
cellPadding:3,
lineWidth: 0.1, // border width
lineColor: [0, 0, 0] // black border color
},
headStyles:{ fillColor: false, textColor: 0 },
bodyStyles:{ valign:'middle', fillColor: false },
alternateRowStyles: { fillColor: false },
columnStyles: { 1: { cellWidth: 110 } }
});
y = doc.lastAutoTable.finalY + 20;
}
// Grand Total totalNumberOfLoanEMI totalNumberOfRecurringEMI totalLoanEMIAmount totalRecurringEMIAmount
doc.setFont(undefined, 'bold');
let lineHeight = 12; // fixed gap between lines
let currentY = y-8;
doc.text(`Total Number of Loan EMI: ${grandTotal.totalNumberOfLoanEMI}`, 20, currentY);
currentY += lineHeight;
doc.text(`Total Number of Recurring Installment: ${grandTotal.totalNumberOfRecurringEMI}`, 20, currentY);
currentY += lineHeight;
doc.text(`Grand Total Loan EMI Amount: ${grandTotal.totalLoanEMIAmount.toLocaleString('en-IN',{minimumFractionDigits:2, maximumFractionDigits:2})}`, 20, currentY);
currentY += lineHeight;
doc.text(`Grand Total Recurring EMI Amount: ${grandTotal.totalRecurringEMIAmount.toLocaleString('en-IN',{minimumFractionDigits:2, maximumFractionDigits:2})}`, 20, currentY);
// Footer with page numbers
const pageCount = doc.internal.getNumberOfPages();
for(let i=1;i<=pageCount;i++){
doc.setPage(i);
doc.setFontSize(9);
doc.setFont(undefined,'normal');
// doc.text(`Generated by Loan Portal - Confidential`,40,doc.internal.pageSize.height-20);
doc.text(`Page ${i} of ${pageCount}`,doc.internal.pageSize.width-60,doc.internal.pageSize.height-20);
}
doc.save(`Demand_Sheet_${userType}_${userName}_${now.toISOString().slice(0,10)}.pdf`);
}
});
});
</script>