« Back to History
company_designation.php
|
20260722_120325.php
Initial Domain Snapshot
Copy Code
<?php /* ============================================================================ File: /erp/company_designation.php Purpose: CRUD for company_designation (company-scoped) Layout : Header/Footer (safe include) + main.css classes (no page CSS) Debug : Append ?debug=1 to see include/redirect diagnostics ============================================================================ */ error_reporting(E_ALL); ini_set('display_errors', 1); /* -------------------- AUTH & PDO -------------------- */ require __DIR__ . '/modules/auth/auth.php'; require_login(); $u = auth_user(); $company_id = (int)$u['company_id']; $user_id = (int)$u['id']; $pdo = $GLOBALS['pdo'] ?? null; if (!$pdo) { require __DIR__ . '/core/db.php'; $pdo = $GLOBALS['pdo']; } require_once __DIR__ . '/helpers/activity_helper.php'; /* (Optional) Tell header/footer to skip their own auth guards if they have any */ if (!defined('MM_SKIP_HEADER_AUTH')) define('MM_SKIP_HEADER_AUTH', true); if (!defined('MM_SKIP_FOOTER_AUTH')) define('MM_SKIP_FOOTER_AUTH', true); /* -------------------- Safe include + DEBUG -------------------- */ 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) to avoid fatal white screen echo ob_get_clean(); $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'; /* -------------------- HELPERS -------------------- */ if (session_status() !== PHP_SESSION_ACTIVE) session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(16)); } $CSRF = $_SESSION['csrf_token']; function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function gv($k,$d=null){ return isset($_GET[$k])? trim((string)$_GET[$k]) : $d; } function pv($k,$d=null){ return isset($_POST[$k])? (is_array($_POST[$k])?$_POST[$k]:trim((string)$_POST[$k])) : $d; } function flash($type,$msg){ $_SESSION['flash'][]=['t'=>$type,'m'=>$msg]; } function flashes(){ if (!empty($_SESSION['flash'])) { foreach ($_SESSION['flash'] as $f){ $cls = $f['t']==='ok'?'ok':'err'; echo '<div class="alert '.$cls.'">'.h($f['m']).'</div>'; } unset($_SESSION['flash']); } } /* -------------------- POST ACTIONS -------------------- */ if ($_SERVER['REQUEST_METHOD']==='POST') { if (!hash_equals($CSRF, pv('csrf'))) { http_response_code(403); exit('CSRF error'); } $action = pv('action',''); try { if ($action==='add') { $name = pv('name',''); $code = pv('code',''); $is_active = pv('is_active','1')==='1' ? 1 : 0; if ($name===''){ throw new Exception('Name required'); } if ($code===''){ throw new Exception('Code required'); } // Uniqueness check (per company) $q = $pdo->prepare("SELECT id FROM company_designation WHERE company_id=? AND (name=? OR code=?) LIMIT 1"); $q->execute([$company_id, $name, $code]); if ($q->fetch()){ throw new Exception('Name or Code already exists'); } $ins = $pdo->prepare("INSERT INTO company_designation (company_id,name,code,is_active,created_by) VALUES (?,?,?,?,?)"); $ins->execute([$company_id, $name, $code, $is_active, $user_id]); activity_create('company', 'company_designation_create', (int)$pdo->lastInsertId(), 'Created designation'); flash('ok','Designation added.'); } elseif ($action==='update') { $id = (int)pv('id',0); $name = pv('name',''); $code = pv('code',''); $is_active = pv('is_active','1')==='1' ? 1 : 0; if ($id<=0) { throw new Exception('Invalid ID'); } if ($name===''){ throw new Exception('Name required'); } if ($code===''){ throw new Exception('Code required'); } $q = $pdo->prepare("SELECT id FROM company_designation WHERE company_id=? AND (name=? OR code=?) AND id<>? LIMIT 1"); $q->execute([$company_id, $name, $code, $id]); if ($q->fetch()){ throw new Exception('Name or Code already exists'); } $up = $pdo->prepare("UPDATE company_designation SET name=?, code=?, is_active=? WHERE id=? AND company_id=?"); $up->execute([$name, $code, $is_active, $id, $company_id]); activity_update('company', 'company_designation_update', $id, 'Updated designation'); flash('ok','Designation updated.'); } elseif ($action==='delete') { $id = (int)pv('id',0); if ($id<=0) { throw new Exception('Invalid ID'); } try { $del = $pdo->prepare("DELETE FROM company_designation WHERE id=? AND company_id=?"); $del->execute([$id, $company_id]); activity_delete('company', 'company_designation_delete', $id, 'Deleted designation'); flash('ok','Designation deleted.'); } catch (PDOException $e) { // FK constraint? → Soft deactivate if ($e->getCode()==='23000') { $soft = $pdo->prepare("UPDATE company_designation SET is_active=0 WHERE id=? AND company_id=?"); $soft->execute([$id, $company_id]); activity_update('company', 'company_designation_deactivate', $id, 'Deactivated designation (in use)'); flash('ok','In use; deactivated instead.'); } else { throw $e; } } } } catch (Exception $ex) { flash('err', $ex->getMessage()); } header('Location: '.$_SERVER['PHP_SELF']); exit; } /* -------------------- EDIT FETCH -------------------- */ $edit_id = (int)gv('edit_id',0); $edit_row = null; if ($edit_id>0){ $st = $pdo->prepare("SELECT id, name, code, is_active FROM company_designation WHERE id=? AND company_id=?"); $st->execute([$edit_id, $company_id]); $edit_row = $st->fetch(PDO::FETCH_ASSOC); } /* -------------------- LIST -------------------- */ $st = $pdo->prepare("SELECT id, name, code, is_active, created_at FROM company_designation WHERE company_id=? ORDER BY is_active DESC, name ASC"); $st->execute([$company_id]); $rows = $st->fetchAll(PDO::FETCH_ASSOC); /* -------------------- HEADER include -------------------- */ $__hdr = mm_include_safe($__HDR_PATH); if ($__DEBUG) { echo '<pre style="background:#0b0f10;color:#8df58d;padding:10px;border-radius:8px;margin:12px 0;white-space:pre-wrap">'; echo "DEBUG: /erp/company_designation.php\n"; echo "User: ".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 "</pre>"; } ?> <?php require_once __DIR__.'/partials/header.php'; ?> <div class="container-fluid py-4"> <div class="mb-4"> <h4 class="fw-bold">Company Designations</h4> <div class="text-muted small">Company ID: <?= (int)$company_id ?></div> </div> <?php flashes(); ?> <!-- ================= FORM SECTION ================= --> <div class="card shadow-sm border-0 mb-4"> <div class="card-body"> <h5 class="fw-bold mb-3"> <?= $edit_row ? 'Edit Designation' : 'Add Designation' ?> </h5> <form method="post" autocomplete="off"> <input type="hidden" name="csrf" value="<?= h($CSRF) ?>"> <input type="hidden" name="action" value="<?= $edit_row ? 'update' : 'add' ?>"> <?php if ($edit_row): ?> <input type="hidden" name="id" value="<?= (int)$edit_row['id'] ?>"> <?php endif; ?> <div class="row g-3"> <div class="col-md-4"> <label class="form-label">Name</label> <input type="text" name="name" value="<?= h($edit_row['name'] ?? '') ?>" class="form-control" required> </div> <div class="col-md-3"> <label class="form-label">Code</label> <input type="text" name="code" value="<?= h($edit_row['code'] ?? '') ?>" class="form-control" required> </div> <div class="col-md-2 d-flex align-items-end"> <div class="form-check"> <input type="checkbox" name="is_active" value="1" class="form-check-input" <?= ($edit_row ? ((int)$edit_row['is_active']===1?'checked':'') : 'checked') ?>> <label class="form-check-label">Active</label> </div> </div> <div class="col-md-3 d-flex align-items-end gap-2"> <button class="btn btn-primary w-100"> <?= $edit_row ? 'Update' : 'Add' ?> </button> <?php if ($edit_row): ?> <a class="btn btn-outline-secondary w-100" href="<?= h($_SERVER['PHP_SELF']) ?>"> Cancel </a> <?php endif; ?> </div> </div> </form> </div> </div> <!-- ================= TABLE SECTION ================= --> <div class="card shadow-sm border-0"> <div class="card-body"> <h6 class="fw-bold mb-3">Designation List</h6> <div class="table-responsive"> <table class="table table-hover align-middle"> <thead class="table-light"> <tr> <th style="width:60px">ID</th> <th>Name</th> <th>Code</th> <th>Status</th> <th>Created</th> <th style="width:180px">Actions</th> </tr> </thead> <tbody> <?php if (!$rows): ?> <tr> <td colspan="6" class="text-center text-muted"> No data found. </td> </tr> <?php else: foreach($rows as $r): ?> <tr> <td><?= (int)$r['id'] ?></td> <td><?= h($r['name']) ?></td> <td><?= h($r['code']) ?></td> <td> <?php if ((int)$r['is_active']===1): ?> <span class="badge bg-success-subtle text-success"> Active </span> <?php else: ?> <span class="badge bg-danger-subtle text-danger"> Inactive </span> <?php endif; ?> </td> <td><?= h($r['created_at']) ?></td> <td class="d-flex gap-2"> <a class="btn btn-sm btn-outline-secondary" href="<?= h($_SERVER['PHP_SELF']) ?>?edit_id=<?= (int)$r['id'] ?>"> Edit </a> <form method="post" onsubmit="return confirm('Delete this designation? (If in use, it will be deactivated)');"> <input type="hidden" name="csrf" value="<?= h($CSRF) ?>"> <input type="hidden" name="action" value="delete"> <input type="hidden" name="id" value="<?= (int)$r['id'] ?>"> <button class="btn btn-sm btn-danger"> Delete </button> </form> </td> </tr> <?php endforeach; endif; ?> </tbody> </table> </div> </div> </div> </div> <?php require_once __DIR__.'/partials/footer.php'; ?>