« Back to History
beam_manager.php
|
20260721_154032.php
Initial Bulk Import
Copy Code
<?php error_reporting(E_ALL); ini_set('display_errors', 1); /* ================= AUTH + DB ================= */ require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('beam_manager'); $company_id = (int)$ctx['company_id']; $user_id = (int)$ctx['user']['id']; $pdo = $ctx['pdo']; require_once __DIR__ . '/helpers/activity_helper.php'; function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } $msg = $err = ''; /* ================= ACTION HANDLER ================= */ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; $beam_no = (int)($_POST['beam_no'] ?? 0); $machine_no = $_POST['machine_no'] ?? ''; $slot = $_POST['slot'] ?? ''; $date = $_POST['action_date'] ?? ''; try { if (!$beam_no || !$machine_no || !$slot) { throw new Exception('Invalid input.'); } if (!$date) { throw new Exception('Date required.'); } $pdo->beginTransaction(); /* ------------------------------------------------- Ensure lifecycle row exists ------------------------------------------------- */ $pdo->prepare(" INSERT INTO beam_life_cycle (beam_no) VALUES (?) ON DUPLICATE KEY UPDATE beam_no = beam_no ")->execute([$beam_no]); /* ------------------------------------------------- Fetch lifecycle JSON FOR UPDATE ------------------------------------------------- */ $lcStmt = $pdo->prepare(" SELECT life_events FROM beam_life_cycle WHERE beam_no = ? FOR UPDATE "); $lcStmt->execute([$beam_no]); $lifeJson = $lcStmt->fetchColumn(); $events = $lifeJson ? json_decode($lifeJson, true) : []; if (!is_array($events)) $events = []; /* ------------------------------------------------- Find LAST OPEN RUN for same machine + slot (load_date present, not cut, not finished) ------------------------------------------------- */ $runIndex = null; /* safety: ensure array */ if (!is_array($events)) { $events = []; } for ($i = count($events) - 1; $i >= 0; $i--) { $ev = $events[$i] ?? null; if (!is_array($ev)) continue; /* normalize machine compare */ $evMachineNo = (string)($ev['machine_no'] ?? ''); $curMachine = (string)$machine_no; if ( $evMachineNo === $curMachine && ($ev['slot'] ?? '') === $slot && !isset($ev['cut_date']) && !isset($ev['finish_date']) && (($ev['action'] ?? '') === 'running') ) { $runIndex = $i; break; } } if ($runIndex === null) { throw new Exception( "Open running lifecycle not found for Beam {$beam_no} on Machine {$machine_no} ({$slot})." ); } /* ------------------------------------------------- CUT / FINISH ACTION ------------------------------------------------- */ $col = ($slot === 'primary') ? 'primary_running_beam' : 'secondary_running_beam'; /* remove from machine */ $pdo->prepare(" UPDATE machine_beam_status SET $col = NULL WHERE company_id = ? AND machine_no = ? ")->execute([$company_id, $machine_no]); if ($action === 'cut') { /* back to stock */ $pdo->prepare(" UPDATE company_beam_stock SET load_type = 'stock', beam_load_date = NULL WHERE company_id = ? AND beam_no = ? ")->execute([$company_id, $beam_no]); /* close run */ $events[$runIndex]['cut_date'] = $date; $events[$runIndex]['action'] = 'cut'; $msg = "Beam $beam_no CUT on $date."; } elseif ($action === 'finish') { /* mark beam as finished */ $pdo->prepare(" UPDATE company_beam_stock SET load_type = 'finished' WHERE company_id = ? AND beam_no = ? ")->execute([$company_id, $beam_no]); /* close running lifecycle event */ $events[$runIndex]['finish_date'] = $date; $events[$runIndex]['action'] = 'finish'; $events[$runIndex]['machine_id'] = (string)$machine_no; /* NOTE: beam_life_cycle table-level finish_date intentionally NOT updated. Lifecycle truth lives inside JSON only. */ $msg = "Beam $beam_no FINISHED on $date."; } else { throw new Exception('Invalid action.'); } /* ------------------------------------------------- Save updated lifecycle JSON ------------------------------------------------- */ $pdo->prepare(" UPDATE beam_life_cycle SET life_events = ? WHERE beam_no = ? ")->execute([ json_encode($events, JSON_UNESCAPED_UNICODE), $beam_no ]); $pdo->commit(); if ($action === 'cut') { activity_status_change('beam', 'beam_manager_cut', $beam_no, 'Beam cut on machine'); } else { activity_status_change('beam', 'beam_manager_finish', $beam_no, 'Beam finished on machine'); } } catch (Exception $e) { $pdo->rollBack(); $err = $e->getMessage(); } } /* ================= VIEW ================= */ $st = $pdo->prepare(" SELECT * FROM machine_beam_status WHERE company_id = ? ORDER BY machine_no "); $st->execute([$company_id]); $rows = $st->fetchAll(PDO::FETCH_ASSOC); require_once __DIR__ . '/partials/header.php'; ?> <div class="wrap container-fluid py-4"> <div class="d-flex justify-content-between align-items-center mb-4"> <div> <h2 class="fw-bold m-0 text-dark"> <i class="bi bi-gear-wide-connected text-primary me-2"></i> Beam Manager </h2> <p class="text-muted small mb-0">Monitor and manage running beams across machine slots</p> </div> <div class="d-flex gap-2"> <span class="badge bg-light text-dark border px-3 py-2"><i class="bi bi-circle-fill text-success me-1 small"></i> Running Beams</span> </div> </div> <?php if ($msg): ?> <div class="alert alert-success shadow-sm border-0 border-start border-4 border-success d-flex align-items-center" role="alert"> <i class="bi bi-check-circle-fill me-2"></i> <div><?= h($msg) ?></div> </div> <?php endif; ?> <?php if ($err): ?> <div class="alert alert-danger shadow-sm border-0 border-start border-4 border-danger d-flex align-items-center" role="alert"> <i class="bi bi-exclamation-triangle-fill me-2"></i> <div><?= h($err) ?></div> </div> <?php endif; ?> <div class="card shadow-sm border-0 overflow-hidden mt-3"> <div class="card-body p-0"> <div class="table-responsive"> <table class="table table-hover align-middle mb-0"> <thead class="bg-light"> <tr> <th class="ps-4 py-3 text-uppercase small fw-bold text-muted">Machine</th> <th class="py-3 text-uppercase small fw-bold text-muted">Slot Type</th> <th class="py-3 text-uppercase small fw-bold text-muted">Beam Number</th> <th class="py-3 text-uppercase small fw-bold text-muted text-center" style="width: 450px;">Operations & Date</th> </tr> </thead> <tbody> <?php foreach ($rows as $r): ?> <?php foreach (['primary', 'secondary'] as $slot): $beam = $r[$slot.'_running_beam'] ?? null; if (!$beam) continue; $slotBadge = ($slot === 'primary') ? 'bg-primary' : 'bg-info text-dark'; ?> <tr> <td class="ps-4"> <div class="d-flex align-items-center"> <div class="avatar-sm me-3 bg-light text-primary rounded-circle d-flex align-items-center justify-content-center fw-bold" style="width:40px; height:40px;"> <?= h($r['machine_no']) ?> </div> <span class="fw-bold text-dark">Unit-<?= h($r['machine_no']) ?></span> </div> </td> <td> <span class="badge <?= $slotBadge ?> text-uppercase px-2 py-1" style="font-size: 0.7rem;"> <?= ucfirst($slot) ?> </span> </td> <td> <code class="fs-6 fw-bold text-secondary"><?= h($beam) ?></code> </td> <td class="pe-4"> <form method="post" class="row g-2 align-items-center justify-content-end"> <input type="hidden" name="beam_no" value="<?= $beam ?>"> <input type="hidden" name="machine_no" value="<?= $r['machine_no'] ?>"> <input type="hidden" name="slot" value="<?= $slot ?>"> <div class="col-auto"> <input type="date" name="action_date" class="form-control form-control-sm border-dashed" value="<?= date('Y-m-d') ?>" required> </div> <div class="col-auto"> <div class="btn-group btn-group-sm shadow-sm"> <button name="action" value="cut" class="btn btn-outline-danger px-3" onclick="return confirm('Confirm CUT for Beam <?= $beam ?>?')"> <i class="bi bi-scissors me-1"></i> Cut </button> <button name="action" value="finish" class="btn btn-warning px-3" onclick="return confirm('Confirm FINISH for Beam <?= $beam ?>? This is irreversible.')"> <i class="bi bi-flag-fill me-1"></i> Finish </button> </div> </div> <div class="col-auto"> <a href="/erp/beam_load.php?beam_no=<?= $beam ?>&beam_slot=<?= $slot ?>" class="btn btn-sm btn-primary px-3 shadow-sm"> <i class="bi bi-arrow-repeat me-1"></i> Load </a> </div> </form> </td> </tr> <?php endforeach; ?> <?php endforeach; ?> <?php if (empty($rows)): ?> <tr> <td colspan="4" class="text-center py-5 text-muted small italic"> <i class="bi bi-inbox fs-2 d-block mb-2 opacity-25"></i> No beams currently running in any machines. </td> </tr> <?php endif; ?> </tbody> </table> </div> </div> </div> </div> <style> /* Custom Table Styling */ .table thead th { border-top: none; letter-spacing: 0.05em; } .border-dashed { border-style: dashed; } .btn-group .btn { border-radius: 6px; } .btn-group .btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; } .btn-group .btn:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } .avatar-sm { border: 2px solid #e9ecef; font-size: 0.9rem; } tr:hover .avatar-sm { background-color: #0d6efd !important; color: white !important; border-color: #0d6efd; } </style> <?php require_once __DIR__ . '/partials/footer.php'; ?>