« Back to History
pasaria_entry_manage.php
|
20260722_120325.php
Initial Domain Snapshot
Copy Code
<?php /* ============================================================================= File: /erp/pasaria_entry_manage.php Title: Pasaria Entry — Manage (Yarn/Beam style skeleton) Notes: Uses existing main.css look (no new global CSS). Safe array access. ========================================================================= */ error_reporting(E_ALL); ini_set('display_errors', 1); require_once __DIR__ . '/modules/activity/activity_logger.php'; /* ------------------------- AUTH + COMPANY SCOPE ------------------------- */ $u = null; $company_id = 0; $pdo = null; $__auth_ok = false; if (is_file(__DIR__ . '/modules/auth/page_acl.php')) { require __DIR__ . '/modules/auth/page_acl.php'; try { $ctx = page_require_access('pasaria_entry_manage'); $u = $ctx['user'] ?? null; $company_id = (int)($ctx['company_id'] ?? 0); $pdo = $ctx['pdo'] ?? null; $__auth_ok = true; } catch (Throwable $e) { /* fallback */ } } if (!$__auth_ok) { require __DIR__ . '/modules/auth/auth.php'; require_login(); $u = auth_user(); $company_id = (int)($u['company_id'] ?? 0); } if (!($pdo instanceof PDO)) { require __DIR__ . '/core/db.php'; } /* ----------------------------- HELPERS --------------------------------- */ function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function dval($s){ return ($s==='' || $s===null) ? null : $s; } function post($k,$d=null){ return isset($_POST[$k]) ? (is_array($_POST[$k])?$_POST[$k]:trim((string)$_POST[$k])) : $d; } /* ------------------------------ CSRF ------------------------------------ */ if (session_status() !== PHP_SESSION_ACTIVE) session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(16)); } $CSRF = $_SESSION['csrf_token']; /* --------------------------- FILTERS / SORT ----------------------------- */ $GET = $_GET; $filters = [ 'q' => trim($GET['q'] ?? ''), 'type' => trim($GET['pasaria_type'] ?? ''), 'machine_no' => trim($GET['machine_no'] ?? ''), 'beam_no' => trim($GET['beam_no'] ?? ''), 'date_from' => trim($GET['date_from'] ?? ''), 'date_to' => trim($GET['date_to'] ?? ''), ]; $sort_by = $GET['sort_by'] ?? 'entry_date'; $sort_dir = strtoupper($GET['sort_dir'] ?? 'DESC') === 'ASC' ? 'ASC' : 'DESC'; $page = max(1, (int)($GET['page'] ?? 1)); $perPage = min(200, max(20, (int)($GET['per_page'] ?? 50))); $offset = ($page - 1) * $perPage; /* ------------------------ DISTINCT TYPES FOR FILTER --------------------- */ $types = []; try { $st = $pdo->prepare("SELECT DISTINCT pasaria_type FROM pasaria_entry WHERE company_id=:cid AND COALESCE(pasaria_type,'')<>'' ORDER BY pasaria_type"); $st->execute([':cid'=>$company_id]); $types = $st->fetchAll(PDO::FETCH_COLUMN,0); } catch(Throwable $e) { $types = []; } /* ------------------------ BUILD WHERE CLAUSE ---------------------------- */ $where = ['company_id = :cid']; $params = [':cid'=>$company_id]; if ($filters['q'] !== '') { $where[] = '(remark LIKE :q OR quality_name LIKE :q OR pasaria_type LIKE :q OR primary_beam LIKE :q OR secondary_beam LIKE :q)'; $params[':q'] = '%' . $filters['q'] . '%'; } if ($filters['type'] !== '') { $where[] = 'pasaria_type = :ptype'; $params[':ptype'] = $filters['type']; } if ($filters['machine_no'] !== '') { $where[] = 'machine_no = :mno'; $params[':mno'] = (int)$filters['machine_no']; } if ($filters['beam_no'] !== '') { $where[] = '(primary_beam_no = :bno OR secondary_beam_no = :bno)'; $params[':bno'] = (int)$filters['beam_no']; } if ($filters['date_from'] !== '') { $where[] = 'entry_date >= :df'; $params[':df'] = $filters['date_from']; } if ($filters['date_to'] !== '') { $where[] = 'entry_date <= :dt'; $params[':dt'] = $filters['date_to']; } $where_sql = 'WHERE ' . implode(' AND ', $where); /* ----------------------------- SAVE (drawer) --------------------------- */ $notice = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST' && post('action') === 'save' && hash_equals($CSRF, (string)post('csrf'))) { $id = (int)post('id'); if ($id > 0) { $payload = [ 'entry_date' => dval(post('entry_date')), 'pasaria_type' => dval(post('pasaria_type')), 'machine_no' => dval(post('machine_no')), 'quality_name' => dval(post('quality_name')), 'quality_id' => dval(post('quality_id')), 'primary_beam' => dval(post('primary_beam')), 'primary_beam_no' => dval(post('primary_beam_no')), 'secondary_beam' => dval(post('secondary_beam')), 'secondary_beam_no' => dval(post('secondary_beam_no')), 'remark' => dval(post('remark')), 'employee' => dval(post('employee')), 'employee_id' => dval(post('employee_id')), ]; $sets = []; $bind = [':id'=>$id, ':cid'=>$company_id]; foreach ($payload as $c=>$v) { $sets[] = "`$c` = :$c"; $bind[":$c"] = $v; } $sql = "UPDATE pasaria_entry SET " . implode(', ', $sets) . " WHERE id = :id AND company_id = :cid"; try { $pdo->prepare($sql)->execute($bind); activity_log([ 'company_id' => $company_id, 'user_id' => (int)($u['id'] ?? 0), 'module' => 'pasaria', 'action_name' => 'edit', 'entity_type' => 'pasaria_entry', 'entity_id' => $id, 'remarks' => 'Updated pasaria entry' ]); $notice = "Saved ✔ (Row #$id)"; // redirect to avoid repost and keep filters header("Location: " . $_SERVER['PHP_SELF'] . "?" . http_build_query($_GET)); exit; } catch(Throwable $e) { $notice = "Save failed: " . $e->getMessage(); } } } /* ------------------------------- EXPORT -------------------------------- */ if (isset($_GET['action']) && $_GET['action'] === 'export') { // simple CSV export $exportType = $_GET['type'] ?? 'csv'; $sql = "SELECT * FROM pasaria_entry $where_sql ORDER BY $sort_by $sort_dir"; $st = $pdo->prepare($sql); $st->execute($params); $rowsExport = $st->fetchAll(PDO::FETCH_ASSOC); if ($exportType === 'csv') { activity_log([ 'company_id' => $company_id, 'user_id' => (int)($u['id'] ?? 0), 'module' => 'pasaria', 'action_name' => 'export', 'entity_type' => 'pasaria_entry', 'entity_id' => 0, 'remarks' => 'Exported pasaria entries CSV' ]); header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename="pasaria_entry_'.$company_id.'.csv"'); $out = fopen('php://output','w'); if ($rowsExport) { fputcsv($out, array_keys($rowsExport[0])); foreach ($rowsExport as $r) fputcsv($out, array_map(function($v){ return (string)$v; }, $r)); } fclose($out); exit; } } /* ------------------------------- FETCH --------------------------------- */ /* total count */ $total = 0; try { $csql = "SELECT COUNT(*) FROM pasaria_entry $where_sql"; $ct = $pdo->prepare($csql); $ct->execute($params); $total = (int)$ct->fetchColumn(); } catch(Throwable $e) { $notice = "Count failed: ".$e->getMessage(); } /* page rows */ $rows = []; try { $sql = "SELECT * FROM pasaria_entry $where_sql ORDER BY $sort_by $sort_dir LIMIT :lim OFFSET :off"; $st = $pdo->prepare($sql); foreach ($params as $k=>$v) $st->bindValue($k, $v); $st->bindValue(':lim', (int)$perPage, PDO::PARAM_INT); $st->bindValue(':off', (int)$offset, PDO::PARAM_INT); $st->execute(); $rows = $st->fetchAll(PDO::FETCH_ASSOC); } catch(Throwable $e) { $notice = "Query error: " . $e->getMessage(); } /* --------------------------- HEADER include ----------------------------- */ $possible_headers = [ __DIR__ . '/partials/header.php', __DIR__ . '/erp/partials/header.php', dirname(__DIR__) . '/partials/header.php', ]; $header_included = false; foreach ($possible_headers as $ph) { if (is_file($ph)) { require_once $ph; $header_included = true; break; } } /* ---------------------------- RENDER HTML ------------------------------- */ ?> <div class="card"> <h3>Pasaria Entry — Manage <small class="muted">rows: <?=count($rows)?> / <?=$total?></small></h3> <form class="filters" method="get" style="margin-bottom:12px;display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end;"> <input type="hidden" name="page" value="1"> <div style="flex:1;min-width:220px"><input type="date" name="date_from" value="<?=h($filters['date_from'])?>" placeholder="From"></div> <div style="flex:1;min-width:220px"><input type="date" name="date_to" value="<?=h($filters['date_to'])?>" placeholder="To"></div> <div style="flex:1;min-width:180px"> <select name="pasaria_type"> <option value="">All Types</option> <?php foreach($types as $t): ?> <option value="<?=h($t)?>" <?= $filters['type']===$t ? 'selected' : '' ?>><?=h($t)?></option> <?php endforeach; ?> </select> </div> <div style="flex:1;min-width:150px"><input type="text" name="machine_no" value="<?=h($filters['machine_no'])?>" placeholder="Machine No"></div> <div style="flex:1;min-width:150px"><input type="text" name="beam_no" value="<?=h($filters['beam_no'])?>" placeholder="Beam No (P/S)"></div> <div style="display:flex;gap:8px;align-items:center;margin-left:auto"> <button class="btn" type="submit">Filter</button> <a class="btn" href="<?= h($_SERVER['PHP_SELF']) ?>">Reset</a> <a class="btn" href="?<?= h(http_build_query(array_merge($_GET,['action'=>'export','type'=>'csv']))) ?>">Export CSV</a> </div> </form> <?php if ($notice): ?> <div class="notice"><?= h($notice) ?></div> <?php endif; ?> <div class="tablewrap"> <table class="table" style="width:100%;border-collapse:separate;"> <thead> <tr> <th style="width:60px">ID</th> <th>Date</th> <th>Type</th> <th>Machine</th> <th>Quality</th> <th>P-Beam</th> <th>P-No</th> <th>S-Beam</th> <th>S-No</th> <th>Emp</th> <th style="width:120px">Actions</th> </tr> </thead> <tbody> <?php if (empty($rows)): ?> <tr><td colspan="11" class="muted" style="padding:18px;text-align:center">No records found.</td></tr> <?php else: foreach ($rows as $r): $rid = (int)($r['id'] ?? 0); $entry_date = $r['entry_date'] ?? ''; $pasaria_type = $r['pasaria_type'] ?? ''; $machine_no = $r['machine_no'] ?? ''; $quality_name = $r['quality_name'] ?? ''; $pbeam = $r['primary_beam'] ?? ''; $pbeam_no = $r['primary_beam_no'] ?? ''; $sbeam = $r['secondary_beam'] ?? ''; $sbeam_no = $r['secondary_beam_no'] ?? ''; $employee = $r['employee'] ?? ''; $employee_id = $r['employee_id'] ?? ''; $empDisplay = $employee !== '' ? $employee : ($employee_id !== '' ? '#'.$employee_id : ''); ?> <tr data-id="<?= $rid ?>"> <td class="ro">#<?= $rid ?></td> <td><?= h(substr($entry_date,0,10)) ?></td> <td><?= h($pasaria_type) ?></td> <td><?= h($machine_no) ?></td> <td><?= h($quality_name) ?></td> <td><?= h($pbeam) ?></td> <td><?= h($pbeam_no) ?></td> <td><?= h($sbeam) ?></td> <td><?= h($sbeam_no) ?></td> <td class="ro"><?= h($empDisplay) ?></td> <td> <a class="btn" href="<?= h($_SERVER['PHP_SELF'].'?'.http_build_query(array_merge($_GET,['edit_id'=>$rid]))) ?>">Edit</a> </td> </tr> <?php endforeach; endif; ?> </tbody> </table> </div> <!-- pagination --> <?php $totalPages = max(1, (int)ceil($total / $perPage)); $qsBase = $_GET; ?> <div style="display:flex;justify-content:space-between;align-items:center;padding-top:10px"> <div class="muted">Showing <?= count($rows) ?> of <?= $total ?> • Page <?= $page ?> / <?= $totalPages ?></div> <div> <?php for ($p=1;$p<=$totalPages;$p++): $qs = $qsBase; $qs['page']=$p; ?> <a class="btn" href="?<?= h(http_build_query($qs)) ?>"><?= $p ?></a> <?php endfor; ?> </div> </div> </div> <?php /* --------------------------- Edit Drawer (if requested) ------------------ */ if (isset($_GET['edit_id'])): $edit_id = (int)$_GET['edit_id']; $row = null; if ($edit_id > 0) { $q = $pdo->prepare("SELECT * FROM pasaria_entry WHERE company_id=:cid AND id=:id LIMIT 1"); $q->execute([':cid'=>$company_id, ':id'=>$edit_id]); $row = $q->fetch(PDO::FETCH_ASSOC) ?: null; } if ($row): ?> <div class="card" style="margin-top:12px;padding:12px"> <h4>Edit Entry #<?= (int)$row['id'] ?></h4> <form method="post" action="<?= h($_SERVER['PHP_SELF'].'?'.http_build_query($_GET)) ?>"> <input type="hidden" name="csrf" value="<?= h($CSRF) ?>"> <input type="hidden" name="action" value="save"> <input type="hidden" name="id" value="<?= (int)$row['id'] ?>"> <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px"> <div><label>Date</label><input type="date" name="entry_date" value="<?= h($row['entry_date'] ?? '') ?>"></div> <div><label>Pasaria Type</label><input type="text" name="pasaria_type" value="<?= h($row['pasaria_type'] ?? '') ?>"></div> <div><label>Machine No</label><input type="text" name="machine_no" value="<?= h($row['machine_no'] ?? '') ?>"></div> </div> <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:8px"> <div><label>Primary Beam</label><input type="text" name="primary_beam" value="<?= h($row['primary_beam'] ?? '') ?>"></div> <div><label>P-Beam No</label><input type="text" name="primary_beam_no" value="<?= h($row['primary_beam_no'] ?? '') ?>"></div> <div><label>Quality Name</label><input type="text" name="quality_name" value="<?= h($row['quality_name'] ?? '') ?>"></div> </div> <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:8px"> <div><label>Secondary Beam</label><input type="text" name="secondary_beam" value="<?= h($row['secondary_beam'] ?? '') ?>"></div> <div><label>S-Beam No</label><input type="text" name="secondary_beam_no" value="<?= h($row['secondary_beam_no'] ?? '') ?>"></div> <div><label>Employee (Name)</label><input type="text" name="employee" value="<?= h($row['employee'] ?? '') ?>"></div> </div> <div style="margin-top:10px;display:flex;gap:8px"> <button class="btn primary" type="submit">Save</button> <a class="btn" href="<?= h($_SERVER['PHP_SELF'].'?'.http_build_query(array_diff_key($_GET,['edit_id'=>true]))) ?>">Cancel</a> </div> </form> </div> <?php endif; endif; /* --------------------------- FOOTER include ----------------------------- */ $possible_footers = [ __DIR__ . '/partials/footer.php', __DIR__ . '/erp/partials/footer.php', dirname(__DIR__) . '/partials/footer.php', ]; foreach ($possible_footers as $pf) { if (is_file($pf)) { require_once $pf; break; } } ?>