38348-vm/includes/DocumentService.php
2026-02-11 01:46:33 +00:00

171 lines
7.0 KiB
PHP

<?php
require_once __DIR__ . '/../db/config.php';
require_once '/usr/share/php/tcpdf/tcpdf.php';
// Extend TCPDF with custom Header and Footer
class MYPDF extends TCPDF {
public function Header() {
$this->SetFont('helvetica', 'B', 20);
$this->Cell(0, 15, 'CRM PRO DOCUMENT', 0, false, 'L', 0, '', 0, false, 'M', 'M');
$this->Ln(10);
$this->SetFont('helvetica', '', 10);
$this->Cell(0, 10, 'Your Trusted Partner in Education', 0, false, 'L', 0, '', 0, false, 'M', 'M');
$this->Line(10, 30, 200, 30);
}
public function Footer() {
$this->SetY(-15);
$this->SetFont('helvetica', 'I', 8);
$this->Cell(0, 10, 'Page '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
}
}
class DocumentService {
public static function generateQuotationPDF($id, $dest = 'I') {
$stmt = db()->prepare("SELECT q.*, c.name as customer_name, c.email as customer_email, c.phone as customer_phone, c.address as customer_address
FROM quotations q
JOIN customers c ON q.customer_id = c.id
WHERE q.id = ? AND q.deleted_at IS NULL");
$stmt->execute([$id]);
$quotation = $stmt->fetch();
if (!$quotation) return null;
$stmt = db()->prepare("SELECT qi.*, p.name as product_name
FROM quotation_items qi
JOIN products p ON qi.product_id = p.id
WHERE qi.quotation_id = ?");
$stmt->execute([$id]);
$items = $stmt->fetchAll();
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('CRM PRO');
$pdf->SetTitle('Quotation ' . $quotation['quotation_number']);
$pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->SetFont('helvetica', '', 10);
$pdf->AddPage();
$html = self::buildHtml($quotation, $items, 'Quotation');
$pdf->writeHTML($html, true, false, true, false, '');
return $pdf->Output('Quotation_' . $quotation['quotation_number'] . '.pdf', $dest);
}
public static function generateInvoicePDF($id, $dest = 'I') {
$stmt = db()->prepare("SELECT i.*, c.name as customer_name, c.email as customer_email, c.phone as customer_phone, c.address as customer_address
FROM invoices i
JOIN customers c ON i.customer_id = c.id
WHERE i.id = ? AND i.deleted_at IS NULL");
$stmt->execute([$id]);
$invoice = $stmt->fetch();
if (!$invoice) return null;
$stmt = db()->prepare("SELECT ii.*, p.name as product_name
FROM invoice_items ii
JOIN products p ON ii.product_id = p.id
WHERE ii.invoice_id = ?");
$stmt->execute([$id]);
$items = $stmt->fetchAll();
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('CRM PRO');
$pdf->SetTitle('Invoice ' . $invoice['invoice_number']);
$pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->SetFont('helvetica', '', 10);
$pdf->AddPage();
$html = self::buildHtml($invoice, $items, 'Invoice');
$pdf->writeHTML($html, true, false, true, false, '');
return $pdf->Output('Invoice_' . $invoice['invoice_number'] . '.pdf', $dest);
}
private static function buildHtml($doc, $items, $type) {
$number_key = ($type == 'Quotation') ? 'quotation_number' : 'invoice_number';
$date_key = 'issue_date';
$expiry_key = ($type == 'Quotation') ? 'expiry_date' : 'due_date';
$expiry_label = ($type == 'Quotation') ? 'Expiry' : 'Due Date';
$html = '
<table cellpadding="5">
<tr>
<td width="50%">
<strong>Bill To:</strong><br>
' . e($doc['customer_name']) . '<br>
' . nl2br(e($doc['customer_address'])) . '<br>
Email: ' . e($doc['customer_email']) . '<br>
Phone: ' . e($doc['customer_phone']) . '
</td>
<td width="50%" align="right">
<strong>' . $type . ' Details:</strong><br>
Number: ' . e($doc[$number_key]) . '<br>
Date: ' . date('M d, Y', strtotime($doc[$date_key])) . '<br>
' . $expiry_label . ': ' . date('M d, Y', strtotime($doc[$expiry_key])) . '<br>
Status: ' . e($doc['status']) . '
</td>
</tr>
</table>
<br><br>
<table border="1" cellpadding="5">
<thead>
<tr style="background-color: #f2f2f2; font-weight: bold;">
<th width="50%">Product/Service Description</th>
<th width="10%" align="center">Qty</th>
<th width="20%" align="right">Unit Price</th>
<th width="20%" align="right">Total</th>
</tr>
</thead>
<tbody>';
foreach ($items as $item) {
$html .= '
<tr>
<td>' . e($item['product_name']) . '</td>
<td align="center">' . number_format($item['quantity'], 2) . '</td>
<td align="right">' . format_currency($item['unit_price']) . '</td>
<td align="right">' . format_currency($item['total_price']) . '</td>
</tr>';
}
$html .= '
</tbody>
</table>
<br><br>
<table cellpadding="5">
<tr>
<td width="60%">
<strong>Notes:</strong><br>
' . nl2br(e($doc['notes'])) . '
</td>
<td width="40%">
<table cellpadding="2">
<tr>
<td><strong>Subtotal:</strong></td>
<td align="right">' . format_currency($doc['subtotal']) . '</td>
</tr>
<tr>
<td><strong>Tax (10%):</strong></td>
<td align="right">' . format_currency($doc['tax_amount']) . '</td>
</tr>
<tr style="font-size: 12pt; font-weight: bold;">
<td><strong>Total:</strong></td>
<td align="right">' . format_currency($doc['total_amount']) . '</td>
</tr>
</table>
</td>
</tr>
</table>';
return $html;
}
}