arif_grafin/CONTENT/ROOT_URI/Admin/Due.php

377 lines
15 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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); }
$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 = abs($deuEMITillDate);
$deuEMITillDate = number_format($deuEMITillDate, 2, '.', '');
}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, '.', '');
}
// 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();
?>
</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
doc.setFont(undefined,'bold');
doc.text(`Grand Total Accounts: ${grandTotal.accounts}`,40,y);
doc.text(`Grand Total Paid Installments: ${grandTotal.paidInstallments}`,40,y+15);
doc.text(`Grand Total Due Installments: ${grandTotal.dueInstallments}`,40,y+30);
doc.text(`Grand Total Due Amount: ${grandTotal.dueAmount.toLocaleString('en-IN',{minimumFractionDigits:2, maximumFractionDigits:2})}`,40,y+45);
// 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>