|
Server IP : 217.21.85.138 / Your IP : 216.73.216.103 Web Server : LiteSpeed System : Linux in-mum-web906.main-hosting.eu 4.18.0-553.37.1.lve.el8.x86_64 #1 SMP Mon Feb 10 22:45:17 UTC 2025 x86_64 User : u915722082 ( 915722082) PHP Version : 7.4.33 Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail MySQL : OFF | cURL : ON | WGET : ON | Perl : OFF | Python : OFF Directory (0755) : /home/u915722082/public_html/js/../pms/admin/ |
| [ Home ] | [ C0mmand ] | [ Upload File ] |
|---|
<!--view_invoice.php-->
<?php
session_start();
if (!isset($_SESSION['admin_id'])) {
header("Location: login.php");
exit;
}
require_once '../config/config.php';
require_once '../config/db.php';
$invoice_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
if (!$invoice_id) {
header("Location: invoices.php");
exit;
}
// Get invoice details
$query = "SELECT i.*,
c.customer_name, c.customer_code, c.contact_person, c.email, c.phone,
c.address_line1, c.address_line2, c.city, c.state, c.pincode, c.country,
c.gst_number, c.pan_number
FROM tbl_invoices i
LEFT JOIN tbl_customers c ON i.customer_id = c.customer_id
WHERE i.invoice_id = $invoice_id";
$result = mysqli_query($con, $query);
if (!$result || mysqli_num_rows($result) === 0) {
die("Invoice not found");
}
$invoice = mysqli_fetch_assoc($result);
$line_items = json_decode($invoice['invoice_items'], true) ?? [];
// Razorpay Keys
$razorpay_key_id = "rzp_live_RlASQKUmGPidcA"; // Replace with your actual Key ID
$razorpay_key_secret = "5ILRjA581ODNePZ5P0OXiszY"; // Replace with your actual Key Secret
// Generate UPI QR Code if not exists
if (empty($invoice['qr_code_image'])) {
// UPI Payment Details
$upi_id = "avstechchandru-1@oksbi";
$payee_name = "The Dot Studios";
$amount = $invoice['final_amount'];
$transaction_note = "Payment for " . $invoice['invoice_code'];
// Create UPI payment string
$upi_string = "upi://pay?pa={$upi_id}&pn=" . urlencode($payee_name) .
"&am={$amount}&tn=" . urlencode($transaction_note) .
"&cu=INR";
// Create directory if not exists
$qr_dir = '../uploads/qr_codes/';
if (!is_dir($qr_dir)) {
mkdir($qr_dir, 0755, true);
}
// Generate QR code filename
$qr_filename = "qr_" . $invoice['invoice_code'] . "_" . time() . ".png";
$qr_path = $qr_dir . $qr_filename;
// Download QR code from API
$qr_api_url = "https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=" . urlencode($upi_string);
// Get the QR code image
$qr_image = file_get_contents($qr_api_url);
if ($qr_image !== false) {
// Save to file
file_put_contents($qr_path, $qr_image);
// Update database
$qr_db_path = 'uploads/qr_codes/' . $qr_filename;
$update_query = "UPDATE tbl_invoices SET qr_code_image = '$qr_db_path' WHERE invoice_id = $invoice_id";
mysqli_query($con, $update_query);
// Set for immediate use
$invoice['qr_code_image'] = $qr_db_path;
}
}
$current_user_id = $_SESSION['admin_id'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<base href="../" />
<title><?php echo $invoice['invoice_code']; ?> - Invoice</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,400,500,600,700" />
<link href="assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css" />
<link href="assets/css/style.bundle.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700;800&display=swap" />
<style>
@media print {
.no-print { display: none !important; }
body { background: white !important; }
.app-sidebar, .app-header, .app-toolbar, .app-footer { display: none !important; }
.app-wrapper { padding: 0 !important; }
.app-main { padding: 0 !important; margin: 0 !important; }
#kt_app_content_container { padding: 20px !important; max-width: 100% !important; }
.invoice-container { box-shadow: none !important; }
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Montserrat', 'Inter', Arial, sans-serif;
color: #000;
background: #f5f5f5;
}
.invoice-container {
max-width: 1000px;
margin: 20px auto;
background: white;
position: relative;
overflow: visible;
}
/* Dark Header Section */
.dark-header {
background: #242b2d;
color: white;
padding: 78px 90px;
position: relative;
overflow: hidden;
}
.dark-header > * {
position: relative;
z-index: 1;
}
.header-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 50px;
}
.company-logo img {
height: 50px;
}
.invoice-meta-header {
text-align: right;
}
.invoice-number {
font-size: 28px;
font-weight: 700;
letter-spacing: 1px;
color: #9d9d9d;
margin-bottom: 5px;
}
.due-date {
font-size: 14px;
color: #9d9d9d;
}
/* Bank Info Section */
.bank-info-section {
margin-top: 30px;
position: relative;
}
.bank-info-title {
font-size: 16px;
font-weight: 700;
color: #9d9d9d;
margin-bottom: 15px;
padding-bottom: 8px;
position: relative;
}
.bank-info-title::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 70%;
height: 1px;
background:rgba(255, 255, 255, 0.2);
}
.bank-info-grid {
display: flex;
justify-content: space-between;
gap: 40px;
margin-top: 20px;
}
.bank-column {
font-size: 13px;
line-height: 1.8;
color: #dfe6e9;
flex: 1;
}
.bank-column:last-child {
flex: 0.8;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.bank-row {
display: flex;
margin-bottom: 8px;
}
.bank-label {
min-width: 110px;
color: #9d9d9d;
}
.bank-value {
color: #9d9d9d;
font-weight: 500;
}
.signature-section {
text-align: right;
}
.signature-img {
max-width: 150px;
margin-bottom: 10px;
margin-left: auto;
}
.signature-name {
font-size: 15px;
font-weight: 600;
color: #9d9d9d;
margin-bottom: 3px;
}
.signature-title {
font-size: 13px;
color: #9d9d9d;
}
/* Footer Info in Dark Section */
.footer-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid rgba(255, 255, 255, 0.2);
}
.thank-you-section {
display: flex;
align-items: center;
gap: 10px;
font-size: 18px;
font-weight: 600;
color: #9d9d9d;
}
.heart-icon {
color: #ff2d00;
font-size: 20px;
}
.contact-info {
text-align: right;
font-size: 13px;
color: #9d9d9d;
line-height: 1.6;
}
.contact-info a {
color: #9d9d9d;
text-decoration: none;
}
/* White Body Section with Watermark */
.invoice-body {
background: #fff;
position: relative;
padding: 78px 90px;
background-image: url('../uploads/invoice_images/watermark.png');
background-repeat: no-repeat;
background-position: top center;
background-size: 750px;
opacity: 0.95;
}
.invoice-body-content {
position: relative;
z-index: 1;
}
/* QR Code Section */
/* QR Code Section - FIXED POSITION */
.qr-code-section {
position: absolute;
top: 470px; /* Fixed pixel position instead of percentage */
right: 70px;
z-index: 100;
/* Remove transform: translateY(-50%); */
}
.qr-code-wrapper {
background: #242b2d;
padding: 6px;
padding-bottom: 4px;
border-radius: 12px;
text-align: center;
}
.qr-code-img {
width: 110px;
height: 110px;
margin-bottom: 5px;
display: block;
border-radius: 5px;
padding: 8px;
background: white;
}
.scan-text {
font-size: 12px;
font-weight: 500;
color: grey;
}
/* Customer Section */
.customer-section {
margin-bottom: 40px;
}
.customer-name {
font-size: 22px;
font-weight: 700;
color: #2d3436;
margin-bottom: 8px;
}
.customer-address {
font-size: 14px;
color: #9d9d9d;
line-height: 1.6;
}
.customer-details-row {
margin-top: 10px;
}
.customer-detail-item {
font-size: 13px;
color: #9d9d9d;
margin-bottom: 4px;
}
.customer-detail-label {
font-weight: 600;
color: #2d3436;
}
/* Total Due Section - EXTENDS TO RIGHT EDGE */
.total-due-section {
margin-bottom: 60px;
padding: 15px 0;
position: relative;
margin-right: -90px;
padding-right: 90px;
}
/* Bottom border extending to container edge */
.total-due-section::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
background: #000;
}
.total-due-label {
font-size: 12px;
font-weight: 600;
color: #a0a0a0;
margin-bottom: 15px;
letter-spacing: 1px;
text-transform: uppercase;
position: relative;
display: inline-block;
}
.total-due-label::after {
content: '';
position: absolute;
left: calc(100% + 10px);
top: 50%;
transform: translateY(-50%);
width: 260px; /* REDUCED width - adjust this number */
height: 1px;
background: #000;
}
.total-due-amount {
font-size: 47px;
font-weight: 500;
color: #ff2d00;
display: flex;
justify-content: flex-end;
gap: 10px;
}
.rupee-symbol {
font-size: 47px;
}
/* Items Table */
.items-table {
width: 100%;
border-collapse: collapse;
margin: 30px 0;
}
.items-table thead {
background: transparent;
}
.items-table th {
padding: 15px 12px;
text-align: left;
font-size: 11px;
font-weight: 700;
color: #95a5a6;
text-transform: uppercase;
letter-spacing: 0.5px;
border-bottom: 1px solid #000;
}
.items-table th.text-right {
text-align: right;
}
.items-table th.text-center {
text-align: center;
}
.items-table tbody tr {
border-bottom: none;
}
.items-table tbody tr:not(:last-child) {
border-bottom: 1px solid #f5f6fa;
}
.items-table td {
padding: 20px 12px;
font-size: 14px;
color: #2d3436;
vertical-align: top;
}
.items-table td.text-right {
text-align: right;
}
.items-table td.text-center {
text-align: center;
}
.items-table td.amount-cell {
color: #ff2d00;
font-weight: 700;
}
.item-category {
font-size: 15px;
font-weight: 700;
color: #2d3436;
margin-bottom: 5px;
}
.item-description {
font-size: 13px;
color: #9d9d9d;
margin-bottom: 8px;
line-height: 1.5;
}
.item-subcategories {
font-size: 12px;
color: #9d9d9d;
}
/* Totals Section */
.totals-section {
margin-top: 40px;
padding: 30px 0;
border-top: 1px solid #000;
}
.totals-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
font-size: 13px;
}
.total-inline-item {
display: flex;
align-items: center;
gap: 15px;
}
.total-inline-label {
color: #9d9d9d;
font-weight: 500;
}
.total-inline-operator {
color: #9d9d9d;
font-weight: 600;
}
.total-inline-value {
color: #2d3436;
font-weight: 700;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.invoice-container {
margin: 10px;
}
.dark-header,
.invoice-body {
padding: 30px 20px;
}
.bank-info-grid {
grid-template-columns: 1fr;
gap: 25px;
}
.qr-code-section {
position: relative;
width: 100%;
height: auto;
}
.totals-row {
flex-direction: column;
gap: 15px;
}
.total-inline-item {
width: 100%;
}
.total-due-section {
margin-left: -20px;
margin-right: -20px;
padding-left: 20px;
padding-right: 20px;
}
}
</style>
</head>
<body id="kt_app_body" data-kt-app-layout="dark-sidebar" data-kt-app-header-fixed="true"
data-kt-app-sidebar-enabled="true" data-kt-app-sidebar-fixed="true"
data-kt-app-sidebar-hoverable="true" data-kt-app-sidebar-push-header="true"
data-kt-app-sidebar-push-toolbar="true" data-kt-app-sidebar-push-footer="true"
data-kt-app-toolbar-enabled="true" class="app-default">
<script>
var defaultThemeMode = "light";
var themeMode;
if (document.documentElement) {
if (document.documentElement.hasAttribute("data-bs-theme-mode")) {
themeMode = document.documentElement.getAttribute("data-bs-theme-mode");
} else {
if (localStorage.getItem("data-bs-theme") !== null) {
themeMode = localStorage.getItem("data-bs-theme");
} else {
themeMode = defaultThemeMode;
}
}
if (themeMode === "system") {
themeMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
document.documentElement.setAttribute("data-bs-theme", themeMode);
}
</script>
<div class="d-flex flex-column flex-root app-root" id="kt_app_root">
<div class="app-page flex-column flex-column-fluid" id="kt_app_page">
<?php include 'includes/header.php'; ?>
<div class="app-wrapper flex-column flex-row-fluid" id="kt_app_wrapper">
<?php include 'includes/sidebar.php'; ?>
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
<div class="d-flex flex-column flex-column-fluid">
<!-- Toolbar -->
<div id="kt_app_toolbar" class="app-toolbar py-3 py-lg-6 no-print">
<div id="kt_app_toolbar_container" class="app-container container-xxl d-flex flex-stack">
<div class="page-title d-flex flex-column justify-content-center flex-wrap me-3">
<h1 class="page-heading d-flex text-gray-900 fw-bold fs-3 flex-column my-0">
📄 View Invoice
</h1>
<ul class="breadcrumb breadcrumb-separatorless fw-semibold fs-7 my-0 pt-1">
<li class="breadcrumb-item text-muted">
<a href="admin/invoices.php" class="text-muted text-hover-primary">Invoices</a>
</li>
<li class="breadcrumb-item">
<span class="bullet bg-gray-500 w-5px h-2px"></span>
</li>
<li class="breadcrumb-item text-muted"><?php echo $invoice['invoice_code']; ?></li>
</ul>
</div>
<div class="d-flex align-items-center gap-2">
<button onclick="window.print()" class="btn btn-light-primary">
<i class="ki-duotone ki-printer fs-2">
<span class="path1"></span>
<span class="path2"></span>
</i>
Print
</button>
<a href="javascript:void(0)" onclick="downloadPDF()" class="btn btn-primary">
<i class="ki-duotone ki-file-down fs-2">
<span class="path1"></span>
<span class="path2"></span>
</i>
Download PDF
</a>
<a href="admin/invoices.php" class="btn btn-light">
<i class="ki-duotone ki-arrow-left fs-2">
<span class="path1"></span>
<span class="path2"></span>
</i>
Back
</a>
</div>
</div>
</div>
<!-- Content -->
<div id="kt_app_content" class="app-content flex-column-fluid">
<div id="kt_app_content_container" class="app-container container-xxl">
<div class="invoice-container" id="invoice-content">
<!-- Dark Header Section -->
<div class="dark-header">
<div class="header-top">
<div class="company-logo">
<img src="../uploads/invoice_images/logo.webp" alt="The Dot Studios" />
</div>
<div class="invoice-meta-header">
<div class="invoice-number"><?php echo htmlspecialchars($invoice['invoice_code']); ?></div>
<div class="due-date">Due by <?php echo date('d M Y', strtotime($invoice['due_date'])); ?></div>
</div>
</div>
<!-- Bank Info Section -->
<div class="bank-info-section">
<div class="bank-info-title">BANK INFO</div>
<div class="bank-info-grid">
<!-- Column 1: Bank Details -->
<div class="bank-column">
<div class="bank-row">
<span class="bank-label">Acc. Holder</span>
<span class="bank-value">: The Dot Studios</span>
</div>
<div class="bank-row">
<span class="bank-label">Acc. Number</span>
<span class="bank-value">: 1667135000005403</span>
</div>
<div class="bank-row">
<span class="bank-label">IFSC Code</span>
<span class="bank-value">: KVBL0001667</span>
</div>
<div class="bank-row">
<span class="bank-label">Bank Name</span>
<span class="bank-value">: Karur Vysya Bank</span>
</div>
</div>
<!-- Column 2: Business Details -->
<div class="bank-column">
<div style="margin-bottom: 8px; color: #9d9d9d; font-weight: 500;">Salem | Coimbatore</div>
<div style="margin-bottom: 8px;">
<span class="bank-label">GSTIN</span>
<span class="bank-value">: 33EQLPM5170G1ZP</span>
</div>
<div>
<span class="bank-label">SAC CODE</span>
<span class="bank-value">: 998314</span>
</div>
</div>
<!-- Column 3: Signature -->
<div class="bank-column signature-section">
<img src="../uploads/invoice_images/signature.png" alt="Signature" class="signature-img" />
<div class="signature-name">Vimal Kumar M</div>
<div class="signature-title">Creative Director</div>
</div>
</div>
</div>
<!-- Footer Info -->
<div class="footer-info">
<div class="thank-you-section">
<span class="heart-icon">❤</span>
<span>Thank You!</span>
</div>
<div class="contact-info">
<div>www.thedotstudios.com | 87780-22004 | info@thedotstudios.com</div>
</div>
</div>
</div>
<!-- QR Code Section -->
<!-- QR Code Section -->
<div class="qr-code-section">
<div class="qr-code-wrapper" id="qr-wrapper" style="cursor: pointer;" title="Click for more payment options">
<?php
if (!empty($invoice['qr_code_image'])):
$qr_web_path = str_replace('../', '', $invoice['qr_code_image']);
?>
<img src="<?php echo htmlspecialchars($qr_web_path); ?>"
alt="QR Code" class="qr-code-img" />
<?php else: ?>
<div class="qr-code-img" style="background: #f0f0f0; display: flex; align-items: center; justify-content: center; color: #999;">
No QR
</div>
<?php endif; ?>
<div class="scan-text">Scan to Pay!!!</div>
</div>
</div>
<!-- Hidden Razorpay Integration -->
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
<script>
// Make QR clickable for card/wallet payments
document.getElementById('qr-wrapper').addEventListener('click', function() {
var options = {
"key": "<?php echo $razorpay_key_id; ?>",
"amount": "<?php echo intval($invoice['final_amount'] * 100); ?>",
"currency": "INR",
"name": "The Dot Studios",
"description": "Payment for <?php echo htmlspecialchars($invoice['invoice_code']); ?>",
"image": "../uploads/invoice_images/logo.webp",
"handler": function (response) {
if (response.razorpay_payment_id) {
// Verify payment
fetch('admin/verify_payment.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
payment_id: response.razorpay_payment_id,
invoice_id: <?php echo $invoice_id; ?>
})
})
.then(res => res.json())
.then(data => {
if (data.success) {
alert('✓ Payment Successful!');
location.reload();
}
});
}
},
"prefill": {
"name": "<?php echo htmlspecialchars($invoice['customer_name']); ?>",
"email": "<?php echo htmlspecialchars($invoice['email'] ?? ''); ?>",
"contact": "<?php echo htmlspecialchars($invoice['phone'] ?? ''); ?>"
},
"theme": {
"color": "#242b2d"
}
};
var rzp = new Razorpay(options);
rzp.open();
});
</script>
<!-- White Body Section -->
<div class="invoice-body">
<div class="invoice-body-content">
<!-- Customer Info & Total Due -->
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 300px; margin-bottom: 30px;">
<div class="customer-section">
<div class="customer-name"><?php echo htmlspecialchars($invoice['customer_name']); ?></div>
<div class="customer-address">
<?php if($invoice['address_line1']): ?>
<?php echo htmlspecialchars($invoice['address_line1']); ?>,<br>
<?php endif; ?>
<?php if($invoice['address_line2']): ?>
<?php echo htmlspecialchars($invoice['address_line2']); ?>,<br>
<?php endif; ?>
<?php if($invoice['city']): ?>
<?php echo htmlspecialchars($invoice['city']); ?><?php if($invoice['state']): ?>, <?php echo htmlspecialchars($invoice['state']); ?><?php endif; ?>.
<?php endif; ?>
</div>
<div class="customer-details-row">
<?php if($invoice['gst_number']): ?>
<div class="customer-detail-item">
<span class="customer-detail-label">GSTIN :</span> <?php echo htmlspecialchars($invoice['gst_number']); ?>
</div>
<?php endif; ?>
<div class="customer-detail-item">
<span class="customer-detail-label">Date Issued :</span> <?php echo date('d M \'y', strtotime($invoice['invoice_date'])); ?>
</div>
</div>
</div>
<div class="total-due-section">
<div class="total-due-label">TOTAL DUE</div>
<div class="total-due-amount">
<span class="rupee-symbol">₹</span>
<span><?php echo number_format($invoice['final_amount'], 2); ?></span>
</div>
</div>
</div>
<!-- Items Table -->
<table class="items-table">
<thead>
<tr>
<th style="width: 5%;">#</th>
<th style="width: 45%;">Item & Description</th>
<th class="text-center" style="width: 12%;">QTY</th>
<th class="text-right" style="width: 18%;">Rate</th>
<th class="text-right" style="width: 20%;">Amount</th>
</tr>
</thead>
<tbody>
<?php if (!empty($line_items)): ?>
<?php $index = 1; ?>
<?php foreach($line_items as $item): ?>
<tr>
<td class="text-center"><?php echo $index++; ?></td>
<td>
<div class="item-category"><?php echo htmlspecialchars($item['name'] ?? $item['description']); ?></div>
<?php if(isset($item['description']) && $item['description'] != $item['name']): ?>
<div class="item-description"><?php echo htmlspecialchars($item['description']); ?></div>
<?php endif; ?>
<?php if(isset($item['subcategories']) && !empty($item['subcategories'])): ?>
<div class="item-subcategories">
<?php echo htmlspecialchars(implode(', ', $item['subcategories'])); ?>
</div>
<?php endif; ?>
</td>
<td class="text-center"><?php echo $item['quantity']; ?></td>
<td class="text-right"><?php echo number_format($item['rate'], 2); ?> ₹</td>
<td class="text-right amount-cell"><?php echo number_format($item['amount'], 2); ?> ₹</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="5" style="text-align: center; padding: 40px; color: #9d9d9d;">No items found</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<!-- Totals Section -->
<div class="totals-section">
<div class="totals-row">
<div class="total-inline-item">
<span class="total-inline-label">Markdown</span>
<span class="total-inline-operator">( - )</span>
<span class="total-inline-value"><?php echo number_format($invoice['discount_amount'] ?? 0, 2); ?> ₹</span>
</div>
<div class="total-inline-item">
<span class="total-inline-label">CGST ( 9% )</span>
<span class="total-inline-operator">( + )</span>
<span class="total-inline-value"><?php echo number_format(($invoice['tax_amount'] ?? 0) / 2, 2); ?> ₹</span>
</div>
<div class="total-inline-item">
<span class="total-inline-label">Sub Total</span>
<span class="total-inline-value"><?php echo number_format($invoice['subtotal'], 2); ?> ₹</span>
</div>
</div>
<div class="totals-row">
<div class="total-inline-item">
<span class="total-inline-label">Down Pmt.</span>
<span class="total-inline-operator">( - )</span>
<span class="total-inline-value"><?php echo number_format($invoice['down_payment'] ?? 0, 2); ?> ₹</span>
</div>
<div class="total-inline-item">
<span class="total-inline-label">SGST ( 9% )</span>
<span class="total-inline-operator">( + )</span>
<span class="total-inline-value"><?php echo number_format(($invoice['tax_amount'] ?? 0) / 2, 2); ?> ₹</span>
</div>
<div class="total-inline-item">
<span class="total-inline-label">Hanging Fire</span>
<span class="total-inline-operator">( + )</span>
<span class="total-inline-value"><?php echo number_format($invoice['hanging_fire'] ?? 0, 2); ?> ₹</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php include 'includes/footer.php'; ?>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="assets/plugins/global/plugins.bundle.js"></script>
<script src="assets/js/scripts.bundle.js"></script>
<?php include 'includes/chat_widget.php'; ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script>
// Replace the download PDF button with this:
function downloadPDF() {
const button = event.target.closest('a');
const originalText = button.innerHTML;
button.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Generating...';
button.style.pointerEvents = 'none';
const element = document.getElementById('invoice-content');
// Configuration for better quality
const opt = {
margin: 0,
filename: '<?php echo $invoice["invoice_code"]; ?>_' + new Date().toISOString().split('T')[0] + '.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: 2,
useCORS: true,
logging: false,
letterRendering: true,
scrollY: -window.scrollY,
scrollX: -window.scrollX
},
jsPDF: {
unit: 'mm',
format: 'a4',
orientation: 'portrait',
compress: true
}
};
// Use html2pdf library
html2canvas(element, opt.html2canvas).then(canvas => {
const imgData = canvas.toDataURL('image/jpeg', opt.image.quality);
const { jsPDF } = window.jspdf;
const pdf = new jsPDF(opt.jsPDF);
const imgWidth = 210; // A4 width in mm
const imgHeight = (canvas.height * imgWidth) / canvas.width;
pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight);
pdf.save(opt.filename);
// Reset button
button.innerHTML = originalText;
button.style.pointerEvents = 'auto';
}).catch(err => {
console.error('PDF generation failed:', err);
alert('Failed to generate PDF. Please try again.');
button.innerHTML = originalText;
button.style.pointerEvents = 'auto';
});
}
</script>
</body>
</html>