« Back to History
warper_performance_report.php
|
20260723_000646.php
Initial Domain Snapshot
Copy Code
<?php /* ============================================================================ File: /erp/warper_performance_report.php Purpose: Warper Performance Report (date range) Notes: - Adds Print + Export PDF buttons (uses browser Print -> Save as PDF). - Headings present: Overall Summary, Quality-wise Summary, Employee-wise Summary. - No inline CSS (main.css changes given separately). ============================================================================*/ $acl_candidates = [ __DIR__ . '/modules/auth/page_acl.php', __DIR__ . '/../modules/auth/page_acl.php', __DIR__ . '/../../modules/auth/page_acl.php', __DIR__ . '/erp/modules/auth/page_acl.php', ]; $acl_loaded = false; foreach ($acl_candidates as $acl) { if (file_exists($acl)) { require_once $acl; $acl_loaded = true; break; } } if (!$acl_loaded) { die("ACL not found"); } /* Bootstrap + ACL */ $ctx = page_require_access('warper_performance_report'); $u = $ctx['user'] ?? null; $company_id = (int)($ctx['company_id'] ?? 0); $pdo = $ctx['pdo'] ?? null; /* fallback include only if $pdo not provided by $ctx (per project rules prefer $ctx['pdo']) */ if (!$pdo && file_exists(__DIR__ . '/core/db.php')) { require_once __DIR__ . '/core/db.php'; } /* Helpers */ if (!function_exists('h')) { function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } } /* Dompdf bootstrap */ $PDF_AVAILABLE = false; $dompdf_autoloaders = [ __DIR__ . '/lib/dompdf/autoload.inc.php', __DIR__ . '/vendor/autoload.php', ]; foreach ($dompdf_autoloaders as $autoload) { if (is_file($autoload)) { require_once $autoload; if (class_exists(\Dompdf\Dompdf::class)) { $PDF_AVAILABLE = true; break; } } } /* Input defaults */ $from = $_GET['from'] ?? date('Y-m-01'); $to = $_GET['to'] ?? date('Y-m-d'); $report = []; $employee_summary = []; $quality_summary = []; $overall = ['total_beams'=>0,'total_taka'=>0.0,'total_meter'=>0.0,'days'=>1]; $db_error = null; if (isset($_GET['from'])) { try { $dt1 = new DateTime($from); $dt2 = new DateTime($to); $overall['days'] = max(1, $dt1->diff($dt2)->days + 1); } catch (Exception $e) { $overall['days'] = 1; } if (!$pdo) { $db_error = "Database connection not available (missing \$ctx['pdo'])."; } else { try { $sql = " SELECT b.*, q.name AS quality_name, e.name AS employee_name FROM beam_entry b LEFT JOIN beam_qualities q ON q.id = b.quality_id AND q.company_id = b.company_id LEFT JOIN company_employee_master e ON e.id = b.employee_id AND e.company_id = b.company_id WHERE b.company_id = :cid AND b.entry_date BETWEEN :f AND :t ORDER BY b.entry_date ASC, b.id ASC "; $stmt = $pdo->prepare($sql); $stmt->execute([ ':cid' => $company_id, ':f' => $from, ':t' => $to, ]); $report = $stmt->fetchAll(PDO::FETCH_ASSOC); /* Build summaries */ foreach ($report as $r) { $overall['total_beams']++; $taka = (float)($r['taka'] ?? 0); $meter = (float)($r['meter'] ?? 0); $overall['total_taka'] += $taka; $overall['total_meter'] += $meter; $ename = trim($r['employee_name'] ?? '') ?: 'Unknown'; if (!isset($employee_summary[$ename])) $employee_summary[$ename] = ['beams'=>0,'taka'=>0.0,'meter'=>0.0]; $employee_summary[$ename]['beams']++; $employee_summary[$ename]['taka'] += $taka; $employee_summary[$ename]['meter'] += $meter; $qname = trim($r['quality_name'] ?? '') ?: 'Unknown'; if (!isset($quality_summary[$qname])) $quality_summary[$qname] = ['beams'=>0,'taka'=>0.0,'meter'=>0.0]; $quality_summary[$qname]['beams']++; $quality_summary[$qname]['taka'] += $taka; $quality_summary[$qname]['meter'] += $meter; } } catch (PDOException $e) { $db_error = $e->getMessage(); } catch (Exception $e) { $db_error = $e->getMessage(); } } } if (($_GET['export'] ?? '') === 'pdf') { if (!$PDF_AVAILABLE) { http_response_code(503); header('Content-Type: text/html; charset=UTF-8'); echo '<h3>PDF export unavailable</h3><p>Dompdf is not installed on this server.</p>'; exit; } ob_start(); ?> <!doctype html> <html> <head> <meta charset="utf-8"> <title>Warper Performance Report PDF</title> <style> @page { margin: 12px 12px; } body { margin: 0; font-family: DejaVu Sans, sans-serif; font-size: 8px; color: #111; } h1 { margin: 0 0 4px; font-size: 13px; } .subhead { margin: 0 0 10px; color: #555; font-size: 9px; } h2 { margin: 12px 0 6px; font-size: 11px; } table { width: 100%; border-collapse: collapse; table-layout: fixed; margin-bottom: 12px; } th, td { border: 1px solid #d9d9d9; padding: 4px 3px; vertical-align: middle; word-break: break-word; } th { background: #f3f4f6; font-size: 7px; } td { font-size: 8px; } </style> </head> <body> <h1>Warper Performance Report</h1> <div class="subhead">From <?= h($from) ?> to <?= h($to) ?></div> <?php if ($db_error): ?> <p><strong>Database error:</strong> <?= h($db_error) ?></p> <?php elseif (!empty($report)): ?> <h2>Overall Summary</h2> <table> <tr> <th>Total Beams</th> <td><?= h($overall['total_beams']) ?></td> <th>Avg Beams / Day</th> <td><?= h(round($overall['total_beams'] / $overall['days'], 2)) ?></td> </tr> <tr> <th>Total Taka</th> <td><?= h(round($overall['total_taka'], 2)) ?></td> <th>Avg Taka / Day</th> <td><?= h(round($overall['total_taka'] / $overall['days'], 2)) ?></td> </tr> <tr> <th>Total Meter</th> <td><?= h(round($overall['total_meter'], 2)) ?></td> <th>Avg Meter / Day</th> <td><?= h(round($overall['total_meter'] / $overall['days'], 2)) ?></td> </tr> <tr> <th>Days</th> <td><?= h($overall['days']) ?></td> <td></td> <td></td> </tr> </table> <h2>Quality-wise Summary</h2> <table> <thead> <tr> <th>Quality</th> <th>Beams</th> <th>Avg Beams / Day</th> <th>Taka</th> <th>Avg Taka / Day</th> <th>Meter</th> <th>Avg Meter / Day</th> </tr> </thead> <tbody> <?php foreach ($quality_summary as $qname => $vals): $avg_beams = round($vals['beams'] / max(1, $overall['days']), 2); $avg_taka = round($vals['taka'] / max(1, $overall['days']), 2); $avg_meter = round($vals['meter'] / max(1, $overall['days']), 2); ?> <tr> <td><?= h($qname) ?></td> <td><?= h($vals['beams']) ?></td> <td><?= h($avg_beams) ?></td> <td><?= h(round($vals['taka'], 2)) ?></td> <td><?= h($avg_taka) ?></td> <td><?= h(round($vals['meter'], 2)) ?></td> <td><?= h($avg_meter) ?></td> </tr> <?php endforeach; ?> </tbody> </table> <h2>Employee-wise Summary</h2> <table> <thead> <tr> <th>Employee</th> <th>Beams</th> <th>Avg Beams / Day</th> <th>Taka</th> <th>Avg Taka / Day</th> <th>Meter</th> <th>Avg Meter / Day</th> </tr> </thead> <tbody> <?php foreach ($employee_summary as $ename => $vals): $avg_beams = round($vals['beams'] / max(1, $overall['days']), 2); $avg_taka = round($vals['taka'] / max(1, $overall['days']), 2); $avg_meter = round($vals['meter'] / max(1, $overall['days']), 2); ?> <tr> <td><?= h($ename) ?></td> <td><?= h($vals['beams']) ?></td> <td><?= h($avg_beams) ?></td> <td><?= h(round($vals['taka'], 2)) ?></td> <td><?= h($avg_taka) ?></td> <td><?= h(round($vals['meter'], 2)) ?></td> <td><?= h($avg_meter) ?></td> </tr> <?php endforeach; ?> </tbody> </table> <?php else: ?> <p>No entries for selected dates. Choose a different range.</p> <?php endif; ?> </body> </html> <?php $pdfHtml = ob_get_clean(); $dompdf = new \Dompdf\Dompdf([ 'isRemoteEnabled' => false, 'defaultFont' => 'DejaVu Sans', ]); $dompdf->loadHtml($pdfHtml, 'UTF-8'); $dompdf->setPaper('A4', 'portrait'); $dompdf->render(); $filename = 'warper_performance_' . preg_replace('/[^0-9-]/', '', $from) . '_to_' . preg_replace('/[^0-9-]/', '', $to) . '.pdf'; $dompdf->stream($filename, ['Attachment' => true]); exit; } /* Include header (mandatory) */ require_once __DIR__ . '/partials/header.php'; ?> <div class="container mt-4 page-warper-report"> <div class="card p-4"> <!-- TOP TOOLBAR (Title + Print / Export) --> <div class="report-toolbar" style="display:flex;justify-content:space-between;align-items:center;gap:12px;"> <div> <h2 class="m-0">Warper Performance Report</h2> <div class="text-muted">Choose date range to view summary</div> </div> <div class="report-actions"> <?php $pdf_qs = http_build_query(['from' => $from, 'to' => $to, 'export' => 'pdf']); ?> <button type="button" class="btn btn-outline-secondary" id="btn-print">Print</button> <a class="btn btn-outline-primary" href="?<?= h($pdf_qs) ?>">Export PDF</a> <a class="btn btn-light" href="#" onclick="window.location.reload(); return false;">Reset</a> </div> </div> <hr /> <!-- Filter form --> <form method="get" class="form-grid mb-4" autocomplete="off"> <div> <label>From Date</label> <input type="date" name="from" class="form-control" value="<?= h($from) ?>"> </div> <div> <label>To Date</label> <input type="date" name="to" class="form-control" value="<?= h($to) ?>"> </div> <div class="align-end"> <button class="btn btn-primary mt-4">Show</button> </div> </form> <?php if ($db_error): ?> <div class="alert alert-danger"> <strong>Database error:</strong> <?= h($db_error) ?> </div> <?php endif; ?> <?php if (!empty($report)): ?> <!-- Overall Summary --> <section id="overall-summary" class="mb-3"> <h4>Overall Summary</h4> <table class="table table-sm"> <tr> <th>Total Beams</th> <td><?= h($overall['total_beams']) ?></td> <th>Avg Beams / Day</th> <td><?= h(round($overall['total_beams'] / $overall['days'], 2)) ?></td> </tr> <tr> <th>Total Taka</th> <td><?= h(round($overall['total_taka'],2)) ?></td> <th>Avg Taka / Day</th> <td><?= h(round($overall['total_taka'] / $overall['days'], 2)) ?></td> </tr> <tr> <th>Total Meter</th> <td><?= h(round($overall['total_meter'],2)) ?></td> <th>Avg Meter / Day</th> <td><?= h(round($overall['total_meter'] / $overall['days'], 2)) ?></td> </tr> <tr> <th>Days</th> <td><?= h($overall['days']) ?></td> <td></td><td></td> </tr> </table> </section> <!-- Quality-wise Summary --> <section id="quality-summary" class="mb-3"> <h4>Quality-wise Summary</h4> <table class="table table-bordered table-sm table-color-quality"> <thead> <tr> <th>Quality</th> <th>Beams</th> <th>Avg Beams / Day</th> <th>Taka</th> <th>Avg Taka / Day</th> <th>Meter</th> <th>Avg Meter / Day</th> </tr> </thead> <tbody> <?php foreach ($quality_summary as $qname => $vals): $avg_beams = round($vals['beams'] / max(1, $overall['days']), 2); $avg_taka = round($vals['taka'] / max(1, $overall['days']), 2); $avg_meter = round($vals['meter'] / max(1, $overall['days']), 2); ?> <tr> <td><?= h($qname) ?></td> <td><?= h($vals['beams']) ?></td> <td><?= h($avg_beams) ?></td> <td><?= h(round($vals['taka'],2)) ?></td> <td><?= h($avg_taka) ?></td> <td><?= h(round($vals['meter'],2)) ?></td> <td><?= h($avg_meter) ?></td> </tr> <?php endforeach; ?> </tbody> </table> </section> <!-- Employee-wise Summary --> <section id="employee-summary" class="mb-3"> <h4>Employee-wise Summary</h4> <table class="table table-bordered table-sm table-color-employee"> <thead> <tr> <th>Employee</th> <th>Beams</th> <th>Avg Beams / Day</th> <th>Taka</th> <th>Avg Taka / Day</th> <th>Meter</th> <th>Avg Meter / Day</th> </tr> </thead> <tbody> <?php foreach ($employee_summary as $ename => $vals): $avg_beams = round($vals['beams'] / max(1, $overall['days']), 2); $avg_taka = round($vals['taka'] / max(1, $overall['days']), 2); $avg_meter = round($vals['meter'] / max(1, $overall['days']), 2); ?> <tr> <td><?= h($ename) ?></td> <td><?= h($vals['beams']) ?></td> <td><?= h($avg_beams) ?></td> <td><?= h(round($vals['taka'],2)) ?></td> <td><?= h($avg_taka) ?></td> <td><?= h(round($vals['meter'],2)) ?></td> <td><?= h($avg_meter) ?></td> </tr> <?php endforeach; ?> </tbody> </table> </section> <?php else: ?> <?php if (!$db_error): ?> <div class="alert alert-info mt-3">No entries for selected dates. Choose a different range.</div> <?php endif; ?> <?php endif; ?> </div> <!-- card --> </div> <!-- container --> <!-- Small JS to trigger print/export --> <script> document.getElementById('btn-print').addEventListener('click', function(){ // print visible page (user can choose printer or Save as PDF) window.print(); }); </script> <?php /* Footer include (mandatory) */ require_once __DIR__ . '/partials/footer.php'; ?>