« Back to History
rapier_efficiency_entry.php
|
20260721_154033.php
Initial Bulk Import
Copy Code
<?php /* ========================================================= Rapier Efficiency – Pick Entry (FINAL, BUG-FIXED) ========================================================= */ require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('rapier_efficiency_entry'); $pdo = $ctx['pdo']; $company_id = (int)$ctx['company_id']; $user_id = (int)($ctx['user']['id'] ?? 0); /* ---------------- Persist machine rows ---------------- */ if (isset($_GET['machine'])) { $_SESSION['rapier_machine_rows'] = max(1, (int)$_GET['machine']); } $machine_rows = $_SESSION['rapier_machine_rows'] ?? 1; /* ---------------- AJAX SAVE ---------------- */ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax'])) { $pick_raw = trim($_POST['pick'] ?? ''); $pick = (float)$pick_raw; if ($pick_raw === '' || $pick <= 0) { echo json_encode(['ok'=>false]); exit; } $mm_raw = trim($_POST['material_meter'] ?? ''); $material_meter = ($mm_raw === '' || (float)$mm_raw <= 0) ? null : round((float)$mm_raw, 3); $sql = " INSERT INTO rapier_efficiency_data (company_id, month, entry_date, machine_no, pick, material_meter, karigar_id, shift, created_by) VALUES (:cid, :m, :d, :mc, :p, :mm, :k, :s, :uid) ON DUPLICATE KEY UPDATE pick = VALUES(pick), material_meter = VALUES(material_meter), karigar_id = VALUES(karigar_id), updated_at = CURRENT_TIMESTAMP "; $st = $pdo->prepare($sql); $st->execute([ ':cid' => $company_id, ':m' => $_POST['month'], ':d' => $_POST['entry_date'], ':mc' => (int)$_POST['mc_no'], ':p' => $pick, ':mm' => $material_meter, ':k' => (int)($_POST['karigar_id'] ?? 0), ':s' => $_POST['shift'], ':uid' => $user_id, ]); echo json_encode(['ok'=>true]); exit; } /* ---------------- Filters ---------------- */ $month = $_GET['month'] ?? date('Y-m'); $date = $_GET['date'] ?? date('Y-m-d'); /* ---------------- Karigar list ---------------- */ $ks = $pdo->prepare(" SELECT id, name FROM company_employee_master WHERE company_id = :cid AND department_id = 20 AND designation_id = 18 ORDER BY name "); $ks->execute([':cid'=>$company_id]); $karigars = $ks->fetchAll(PDO::FETCH_ASSOC); /* ---------------- Existing data ---------------- */ $data=[]; $st=$pdo->prepare(" SELECT * FROM rapier_efficiency_data WHERE company_id = ? AND month = ? AND entry_date = ? "); $st->execute([$company_id,$month,$date]); foreach($st as $r){ $data[$r['shift']][$r['machine_no']]=$r; } function sel($a,$b){ return ((string)$a === (string)$b) ? 'selected' : ''; } require_once __DIR__ . '/partials/header.php'; ?> <div class="wrap full-page-table"> <h2 class="title">Rapier Efficiency – Pick Entry</h2> <form method="get" class="card form-card"> <div class="form-cols-4"> <div class="form-group"> <label>Date</label> <input type="date" name="date" value="<?=htmlspecialchars($date)?>"> </div> <div class="form-group"> <label>Month</label> <input type="month" name="month" value="<?=htmlspecialchars($month)?>"> </div> <div class="form-group"> <label>Machine</label> <input type="number" name="machine" min="1" value="<?=$machine_rows?>"> </div> <div class="form-group"> <button class="btn">Load</button> </div> </div> </form> <?php function render_table($shift,$rows,$data,$karigars){ ?> <h3><?=$shift?></h3> <div class="tablewrap"> <table class="table" data-shift="<?=$shift?>"> <thead> <tr> <th>Mc</th> <th>Pick</th> <th>Material Meter</th> <th>Karigar</th> </tr> </thead> <tbody> <?php for($i=1;$i<=$rows;$i++): $row=$data[$shift][$i]??[]; ?> <tr data-mc="<?=$i?>"> <td><?=$i?></td> <td> <input type="text" inputmode="decimal" class="pick" value="<?=htmlspecialchars($row['pick']??'')?>"> </td> <td> <input type="text" inputmode="decimal" class="material-meter" value="<?=htmlspecialchars($row['material_meter']??'')?>"> </td> <td> <div style="display:flex;gap:6px;align-items:center;"> <select class="karigar" style="flex:1;"> <option value="">--select--</option> <?php foreach($karigars as $k): ?> <option value="<?=$k['id']?>" <?=sel($row['karigar_id']??'', $k['id'])?>><?=$k['name']?></option> <?php endforeach ?> </select> <button type="button" class="btn btn-ghost copy-top">↑</button> <span class="row-dirty" style="display:none;color:#f59e0b;font-size:18px;">•</span> <span class="row-saved" style="display:none;color:#16a34a;font-weight:700;font-size:16px;">✓</span> </div> </td> </tr> <?php endfor ?> </tbody> </table> </div> <?php } ?> <?php render_table('Day',$machine_rows,$data,$karigars); render_table('Night',$machine_rows,$data,$karigars); ?> </div> <script> function normalizeRow(tr){ const p = tr.querySelector('.pick'); const m = tr.querySelector('.material-meter'); if (p) { const v = p.value.trim(); if (v === '' || isNaN(parseFloat(v)) || parseFloat(v) <= 0) p.value=''; } if (m) { const v = m.value.trim(); if (v === '' || isNaN(parseFloat(v)) || parseFloat(v) <= 0) m.value=''; } } function markDirty(tr){ tr.querySelector('.row-dirty').style.display='inline'; tr.querySelector('.row-saved').style.display='none'; } function saveRow(tr){ normalizeRow(tr); const pickEl = tr.querySelector('.pick'); const pick = pickEl ? pickEl.value.trim() : ''; if (pick === '' || isNaN(parseFloat(pick)) || parseFloat(pick) <= 0) return; const fd = new FormData(); fd.append('ajax',1); fd.append('month','<?=$month?>'); fd.append('entry_date','<?=$date?>'); fd.append('mc_no',tr.dataset.mc); fd.append('pick',pick); fd.append('material_meter', tr.querySelector('.material-meter').value.trim()); fd.append('karigar_id', tr.querySelector('.karigar').value); fd.append('shift', tr.closest('table').dataset.shift); fetch(location.href,{method:'POST',body:fd}) .then(r=>r.json()) .then(j=>{ if(j.ok){ tr.querySelector('.row-dirty').style.display='none'; const ok = tr.querySelector('.row-saved'); ok.style.display='inline'; ok.title = 'Saved at ' + new Date().toLocaleTimeString([],{ hour:'2-digit', minute:'2-digit' }); } }); } /* ENTER = SAVE + NEXT ROW (COLUMN AWARE) */ document.addEventListener('keydown',e=>{ if(e.key!=='Enter') return; const el=e.target; if(el.tagName==='SELECT') return; if(!el.matches('input')) return; const tr=el.closest('tr'); if(!tr) return; markDirty(tr); saveRow(tr); e.preventDefault(); const next=tr.nextElementSibling; if(!next) return; let sel='.pick'; if(el.classList.contains('material-meter')) sel='.material-meter'; setTimeout(()=>next.querySelector(sel)?.focus(),0); }); /* typing marks dirty */ document.addEventListener('input',e=>{ if(e.target.classList.contains('pick')|| e.target.classList.contains('material-meter')){ markDirty(e.target.closest('tr')); } }); /* karigar change */ document.addEventListener('change',e=>{ if(!e.target.classList.contains('karigar')) return; const tr=e.target.closest('tr'); markDirty(tr); saveRow(tr); }); /* copy from above */ document.addEventListener('click',e=>{ if(!e.target.classList.contains('copy-top')) return; const tr=e.target.closest('tr'); const prev=tr.previousElementSibling; if(!prev) return; const v=prev.querySelector('.karigar').value; if(!v) return; tr.querySelector('.karigar').value=v; markDirty(tr); saveRow(tr); }); </script> <?php require_once __DIR__ . '/partials/footer.php'; ?>