« Back to History
machines_manage.php
|
20260722_120325.php
Initial Domain Snapshot
Copy Code
<?php /* ============================================================================= File: /erp/machines_manage.php Purpose: Manage `machines` (list + edit/create) Layout : Header/Footer include (safe) + main.css classes (no page CSS) Debug : Append ?debug=1 to see include/redirect diagnostics ============================================================================= */ error_reporting(E_ALL); ini_set('display_errors', 1); /* ---------------- 1) AUTH (template order) ---------------- */ require __DIR__ . '/modules/auth/page_acl.php'; require_once __DIR__ . '/modules/activity/activity_logger.php'; $ctx = page_require_access('machines_manage'); // ACL slug for this page $u = $ctx['user'] ?? null; $company_id = (int)($ctx['company_id'] ?? 0); $pdo = $ctx['pdo'] ?? null; if (!$pdo) { require __DIR__ . '/core/db.php'; $pdo = $GLOBALS['pdo']; } /* (Optional) Tell header/footer to skip internal auth if they check this flag */ if (!defined('MM_SKIP_HEADER_AUTH')) define('MM_SKIP_HEADER_AUTH', true); if (!defined('MM_SKIP_FOOTER_AUTH')) define('MM_SKIP_FOOTER_AUTH', true); /* ---------------- 2) Safe include helpers + DEBUG toggle ---------------- */ function mm_include_safe($file){ $res = ['file'=>$file,'exists'=>file_exists($file),'included'=>false,'error'=>null,'headers'=>[]]; if (!$res['exists']) return $res; try { ob_start(); include $file; // include (not require) so fatal won't kill the page $out = ob_get_clean(); echo $out; $res['included'] = true; if (function_exists('headers_list')) $res['headers'] = headers_list(); } catch (Throwable $e) { @ob_end_clean(); $res['error'] = $e->getMessage(); echo '<div class="alert err" style="margin:12px 0;">'. 'Include error in <b>'.htmlspecialchars($file).'</b>: '.htmlspecialchars($e->getMessage()). '</div>'; } return $res; } $__HDR_PATH = __DIR__ . '/partials/header.php'; $__FTR_PATH = __DIR__ . '/partials/footer.php'; $__DEBUG = isset($_GET['debug']) && $_GET['debug'] == '1'; /* ---------------- 3) Page helpers ---------------- */ function mm_h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function mm_cols(PDO $pdo, string $table): array { $out=[]; try{ foreach($pdo->query("SHOW COLUMNS FROM `$table`") as $r){ $out[$r['Field']]=$r; } } catch(Throwable $e){} return $out; } function mm_has(array $cols, string $name){ return isset($cols[$name]); } /* ---------------- 4) Table meta & editable map ---------------- */ $C = mm_cols($pdo, 'machines'); $EDITABLE = [ 'code'=>'text','name'=>'text','group_slug'=>'text','machine_type'=>'text','jala_no'=>'text','reed'=>'text', 'karigar1_id'=>'number','karigar2_id'=>'number','quality_id'=>'number','design'=>'text','color'=>'text', 'avg_daily_production'=>'number','status'=>'select','notes'=>'textarea','is_active'=>'number' ]; $OPTIONS = ['status'=>['Active'=>'Active','Inactive'=>'Inactive']]; /* ---------------- 5) Actions (create/update) ---------------- */ $action = $_POST['action'] ?? $_GET['action'] ?? 'list'; $msg=''; $err=''; if (in_array($action, ['create','update'], true)) { try { $is_update = ($action === 'update'); $id = $is_update ? (int)($_POST['id'] ?? 0) : 0; $data=[]; foreach($EDITABLE as $f=>$t){ if(!mm_has($C,$f)) continue; $v = $_POST[$f] ?? null; if ($t==='number') $v = ($v===''||$v===null) ? null : 0 + $v; else $v = ($v===null) ? null : trim((string)$v); $data[$f] = $v; } if (mm_has($C,'company_id')) $data['company_id'] = $company_id; if ($is_update) { if ($id<=0) throw new RuntimeException('Invalid ID.'); $sets=[]; $vals=[]; foreach($data as $k=>$v){ $sets[]="`$k`=?"; $vals[]=$v; } $sql = "UPDATE `machines` SET ".implode(',',$sets)." WHERE id=?".(mm_has($C,'company_id')?' AND company_id=?':''); $vals[]=$id; if (mm_has($C,'company_id')) $vals[]=$company_id; $pdo->prepare($sql)->execute($vals); activity_log([ 'company_id' => $company_id, 'user_id' => (int)($u['id'] ?? 0), 'module' => 'machines', 'action_name' => 'edit', 'entity_type' => 'machine', 'entity_id' => $id, 'remarks' => 'Updated machine master' ]); $msg = "Machine #$id updated."; } else { $cols = array_keys($data); $ph = array_fill(0, count($cols), '?'); $sql = "INSERT INTO `machines` (`".implode('`,`',$cols)."`) VALUES (".implode(',',$ph).")"; $pdo->prepare($sql)->execute(array_values($data)); $new_machine_id = (int)$pdo->lastInsertId(); activity_log([ 'company_id' => $company_id, 'user_id' => (int)($u['id'] ?? 0), 'module' => 'machines', 'action_name' => 'create', 'entity_type' => 'machine', 'entity_id' => $new_machine_id, 'remarks' => 'Created machine master' ]); $msg = "New machine added (ID ".$pdo->lastInsertId().")."; } $action = 'list'; } catch(Throwable $e){ $err = $e->getMessage(); } } /* ---------------- 6) Fetch for edit ---------------- */ $row=[]; if ($action==='edit'){ $id=(int)($_GET['id']??0); if($id>0){ $sql="SELECT * FROM `machines` WHERE id=?".(mm_has($C,'company_id')?' AND company_id=?':''); $vals=[$id]; if(mm_has($C,'company_id')) $vals[]=$company_id; $st=$pdo->prepare($sql); $st->execute($vals); $row=$st->fetch(PDO::FETCH_ASSOC) ?: []; if(!$row){ $err="Record not found or not in your company."; $action='list'; } } else { $row=[]; } } /* ---------------- 7) Listing data ---------------- */ $per_page=20; $page=max(1,(int)($_GET['p']??1)); $offset=($page-1)*$per_page; $q = trim((string)($_GET['q'] ?? '')); $list=[]; $total=0; if ($action==='list'){ $where = mm_has($C,'company_id') ? "WHERE company_id=?" : "WHERE 1=1"; $args = mm_has($C,'company_id') ? [$company_id] : []; if ($q!==''){ $where .= " AND (`code` LIKE ? OR `name` LIKE ?)"; $args[]="%$q%"; $args[]="%$q%"; } $st=$pdo->prepare("SELECT COUNT(*) FROM `machines` $where"); $st->execute($args); $total=(int)$st->fetchColumn(); $st=$pdo->prepare("SELECT * FROM `machines` $where ORDER BY id DESC LIMIT $per_page OFFSET $offset"); $st->execute($args); $list = $st->fetchAll(PDO::FETCH_ASSOC); } /* ---------------- 8) HEADER include (safe) ---------------- */ $__hdr = mm_include_safe($__HDR_PATH); /* ---------------- 9) Optional DEBUG panel ---------------- */ if ($__DEBUG) { echo '<pre style="background:#0b0f10;color:#8df58d;padding:10px;border-radius:8px;margin:12px 0;white-space:pre-wrap">'; echo "DEBUG: /erp/machines_manage.php\n"; echo "User: ".mm_h($u['name'] ?? 'N/A')." | Company: ".$company_id."\n"; echo "HEADER exists: ".($__hdr['exists']?'yes':'no')." included: ".($__hdr['included']?'yes':'no')."\n"; if ($__hdr['error']) echo "HEADER error: ".$__hdr['error']."\n"; $loc = array_values(array_filter(($__hdr['headers']??[]), fn($h)=>stripos($h,'Location:')===0)); if ($loc) echo ">>> Location header sent by header.php: {$loc[0]}\n"; echo "Action: $action | q='".mm_h($q)."'\n"; echo "</pre>"; } ?> <!-- ========================= 10) PAGE BODY (main.css classes) ========================= --> <div class="wrap container-fluid py-4"> <div class="card border-0 shadow-sm mb-4"> <div class="card-body d-flex align-items-center justify-content-between py-3"> <div class="d-flex align-items-center gap-3"> <div class="rounded-3 shadow-sm d-flex align-items-center justify-content-center text-white fw-bold" style="width:45px; height:45px; background: linear-gradient(135deg,#34A853,#A7D8DE);"> MM </div> <div> <h4 class="fw-bold m-0 text-dark">Machine Master</h4> <small class="text-muted">Manage, View, and Update factory assets</small> </div> </div> <?php if($action === 'list'): ?> <a href="?action=edit&id=0" class="btn btn-primary px-4 fw-bold shadow-sm"> <i class="bi bi-plus-lg me-2"></i> Add New Machine </a> <?php endif; ?> </div> </div> <?php if($msg): ?> <div class="alert alert-success alert-dismissible fade show shadow-sm border-0 border-start border-4 border-success mb-4"> <i class="bi bi-check-circle-fill me-2"></i> <?= mm_h($msg) ?> <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> <?php endif; ?> <?php if($err): ?> <div class="alert alert-danger alert-dismissible fade show shadow-sm border-0 border-start border-4 border-danger mb-4"> <i class="bi bi-exclamation-octagon-fill me-2"></i> <?= mm_h($err) ?> <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> <?php endif; ?> <?php if($action === 'list'): ?> <div class="card border-0 shadow-sm mb-4"> <div class="card-body"> <form method="get" class="row g-3 align-items-center"> <input type="hidden" name="action" value="list"> <div class="col-md-8"> <div class="input-group"> <span class="input-group-text bg-light border-end-0"><i class="bi bi-search text-muted"></i></span> <input class="form-control border-start-0 ps-0 shadow-none" type="text" name="q" placeholder="Search by code or machine name..." value="<?= mm_h($q) ?>"> </div> </div> <div class="col-md-4 d-flex gap-2"> <button type="submit" class="btn btn-dark px-4 shadow-sm">Search</button> <a href="?action=list" class="btn btn-light border px-4">Reset</a> </div> </form> </div> </div> <div class="card border-0 shadow-sm overflow-hidden"> <div class="table-responsive"> <table class="table table-hover align-middle mb-0"> <thead class="bg-light"> <tr class="small text-uppercase fw-bold text-muted"> <th class="ps-4">ID</th> <?php if(mm_has($C,'code')): ?><th>Code</th><?php endif; ?> <?php if(mm_has($C,'name')): ?><th>Name</th><?php endif; ?> <?php if(mm_has($C,'machine_type')): ?><th>Type</th><?php endif; ?> <?php if(mm_has($C,'status')): ?><th>Status</th><?php endif; ?> <?php if(mm_has($C,'karigar1_id')): ?><th>Operator 1</th><?php endif; ?> <?php if(mm_has($C,'quality_id')): ?><th>Running Quality</th><?php endif; ?> <?php if(mm_has($C,'updated_at')): ?><th>Last Update</th><?php endif; ?> <th class="text-end pe-4">Actions</th> </tr> </thead> <tbody class="border-top-0"> <?php foreach($list as $r): ?> <tr> <td class="ps-4 text-muted small">#<?= (int)$r['id'] ?></td> <?php if(mm_has($C,'code')): ?><td><span class="fw-bold text-dark"><?= mm_h($r['code'] ?? '') ?></span></td><?php endif; ?> <?php if(mm_has($C,'name')): ?><td><?= mm_h($r['name'] ?? '') ?></td><?php endif; ?> <?php if(mm_has($C,'machine_type')): ?> <td><span class="badge bg-light text-dark border px-2"><?= mm_h($r['machine_type'] ?? '') ?></span></td> <?php endif; ?> <?php if(mm_has($C,'status')): ?> <td> <?php $status_class = ($r['status'] === 'Active') ? 'bg-success' : 'bg-secondary'; ?> <span class="badge rounded-pill <?= $status_class ?> px-2" style="font-size: 0.7rem;"> <?= mm_h($r['status'] ?? 'N/A') ?> </span> </td> <?php endif; ?> <?php if(mm_has($C,'karigar1_id')): ?><td><small><?= mm_h($r['karigar1_id'] ?? '-') ?></small></td><?php endif; ?> <?php if(mm_has($C,'quality_id')): ?><td><span class="text-primary small fw-bold"><?= mm_h($r['quality_id'] ?? '-') ?></span></td><?php endif; ?> <?php if(mm_has($C,'updated_at')): ?> <td><div class="small text-muted"><?= date('d M, H:i', strtotime($r['updated_at'])) ?></div></td> <?php endif; ?> <td class="text-end pe-4"> <a href="?action=edit&id=<?= (int)$r['id'] ?>" class="btn btn-sm btn-outline-primary rounded-pill px-3"> <i class="bi bi-pencil-square me-1"></i> Edit </a> </td> </tr> <?php endforeach; ?> <?php if(!$list): ?> <tr><td colspan="10" class="text-center py-5 text-muted italic">No machines found matches your criteria.</td></tr> <?php endif; ?> </tbody> </table> </div> <?php if($total > $per_page): $pages=(int)ceil($total/$per_page); ?> <div class="card-footer bg-white py-3"> <nav class="d-flex justify-content-between align-items-center"> <div class="small text-muted">Showing page <b><?= $page ?></b> of <b><?= $pages ?></b> (Total <?= $total ?> records)</div> <ul class="pagination pagination-sm mb-0"> <li class="page-item <?= ($page <= 1) ? 'disabled' : '' ?>"> <a class="page-link shadow-none" href="?action=list&p=<?=($page-1)?>&q=<?=urlencode($q)?>">Previous</a> </li> <li class="page-item active"><a class="page-link shadow-none"><?= $page ?></a></li> <li class="page-item <?= ($page >= $pages) ? 'disabled' : '' ?>"> <a class="page-link shadow-none" href="?action=list&p=<?=($page+1)?>&q=<?=urlencode($q)?>">Next</a> </li> </ul> </nav> </div> <?php endif; ?> </div> <?php endif; ?> <?php if($action === 'edit'): $is_new = empty($row); $rid = $row['id'] ?? 0; ?> <div class="row justify-content-center"> <div class="col-lg-8"> <div class="card border-0 shadow"> <div class="card-header bg-white py-3 d-flex align-items-center gap-2"> <i class="bi bi-cpu text-primary fs-4"></i> <h5 class="fw-bold m-0"><?= $is_new ? 'New Machine Registration' : 'Edit Machine Details' ?></h5> </div> <div class="card-body p-4"> <form method="post"> <input type="hidden" name="action" value="<?= $is_new ? 'create':'update' ?>"> <?php if(!$is_new): ?><input type="hidden" name="id" value="<?= (int)$rid ?>"><?php endif; ?> <div class="row g-3"> <?php foreach($EDITABLE as $field=>$type): if(!mm_has($C,$field)) continue; $val = $is_new ? '' : ($row[$field] ?? ''); ?> <div class="<?= in_array($type, ['textarea']) ? 'col-12' : 'col-md-6' ?>"> <label class="form-label small fw-bold text-muted text-uppercase"><?= str_replace('_',' ',$field) ?></label> <?php if($type === 'textarea'): ?> <textarea name="<?= mm_h($field) ?>" class="form-control" rows="3"><?= mm_h($val) ?></textarea> <?php elseif($type === 'select'): $ops = $OPTIONS[$field] ?? []; ?> <select name="<?= mm_h($field) ?>" class="form-select"> <option value="">— Select —</option> <?php foreach($ops as $k=>$lbl): ?> <option value="<?= mm_h($k) ?>" <?= ($val===$k)?'selected':'' ?>><?= mm_h($lbl) ?></option> <?php endforeach; ?> </select> <?php else: ?> <input type="<?= $type==='number'?'number':'text' ?>" name="<?= mm_h($field) ?>" class="form-control" value="<?= mm_h((string)$val) ?>"> <?php endif; ?> </div> <?php endforeach; ?> </div> <div class="mt-4 pt-4 border-top d-flex gap-2"> <button type="submit" class="btn btn-primary px-5 fw-bold shadow"> <i class="bi bi-cloud-check me-2"></i><?= $is_new ? 'Register Machine' : 'Update Record' ?> </button> <a href="?action=list" class="btn btn-light border px-4">Cancel</a> </div> </form> </div> </div> </div> </div> <?php endif; ?> </div> <style> .page-link { border-radius: 6px !important; margin: 0 2px; color: #495057; } .page-item.active .page-link { background-color: #0d6efd; border-color: #0d6efd; } .form-label { margin-bottom: 0.3rem; font-size: 0.75rem; letter-spacing: 0.5px; } .table thead th { border-bottom-width: 1px; } tr:hover { background-color: #f8faff !important; } </style>