« Back to History
warper_beam_entry_with_stock.php
|
20260722_120325.php
Initial Domain Snapshot
Copy Code
<?php /* ====================================================================== FILE: /erp/public/warper_beam_entry.php PURPOSE: Warper-only Beam Entry (STRICT dept_id=22) with session-based selection NOTE: No DB writes for user↔employee mapping. No page_acl include. ====================================================================== */ error_reporting(E_ALL); ini_set('display_errors', 1); /* ---------------- Quick config (optional) ---------------- */ $FORCE_EMP_ID = 0; // e.g. 25 for emergency; keep 0 normally /* =================== A) DB bootstrap ===================== */ $pdo = $pdo ?? null; if (!$pdo instanceof PDO) { $dbfile = __DIR__.'/../core/db.php'; if (is_file($dbfile)) require_once $dbfile; if (!$pdo instanceof PDO && isset($GLOBALS['pdo']) && $GLOBALS['pdo'] instanceof PDO) $pdo = $GLOBALS['pdo']; if (!$pdo instanceof PDO && defined('DB_HOST')) { try { $pdo = new PDO( 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC ] ); } catch (Throwable $e) {} } } if (!$pdo instanceof PDO) { http_response_code(500); echo 'DB not connected'; exit; } /* =================== B) Auth (no re-login loop) ===================== */ if (session_status() !== PHP_SESSION_ACTIVE) session_start(); $company_id=0; $user_id=0; $user_name=''; $user_role=''; $auth = __DIR__.'/../modules/auth/auth.php'; if (is_file($auth) && !function_exists('users_table_columns')) require_once $auth; $u = function_exists('auth_user') ? auth_user() : []; if ((!$u || empty($u['id'])) && function_exists('require_login')) { require_login(); // only if not logged in $u = function_exists('auth_user') ? auth_user() : []; } $company_id = (int)($u['company_id'] ?? 0); $user_id = (int)($u['id'] ?? 0); $user_name = (string)($u['name'] ?? ''); $user_role = (string)($u['role'] ?? ''); if ($company_id<=0 || $user_id<=0) { http_response_code(401); exit('Unauthorized'); } /* =================== C) Helpers ===================== */ function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function postv($k,$d=null){ return isset($_POST[$k]) ? (is_string($_POST[$k])?trim($_POST[$k]):$_POST[$k]) : $d; } function getv ($k,$d=null){ return isset($_GET[$k]) ? (is_string($_GET[$k]) ?trim($_GET[$k]) :$_GET[$k]) : $d; } function cols(PDO $pdo,$t){ try{$r=$pdo->query("SHOW COLUMNS FROM `$t`")->fetchAll(PDO::FETCH_ASSOC);$m=[];foreach($r as $c)$m[strtolower($c['Field'])]=1;return $m;}catch(Throwable $e){return[];}} /* =================== D) Column detection ===================== */ $be = cols($pdo,'beam_entry'); $has_beam_no = isset($be['beam_no']); $has_meter = isset($be['meter']); $has_tar = isset($be['tar']); $has_qid = isset($be['quality_id']); $has_created = isset($be['created_by']); $bq = cols($pdo,'beam_qualities'); $bq_has_tar = isset($bq['tar']); /* =================== E) Resolve employee_id (dept=22) – session based (CEM) ===================== */ /* Order: 1) FORCE id 2) Session pick (warper_emp_id) 3) users.employee_id → company_employee_master.id (validate dept 22) 4) unique name match in CEM dept 22 Else: show dropdown (CEM dept 22) and store in session (no DB writes) */ $emp_id = 0; if ($FORCE_EMP_ID>0) $emp_id = (int)$FORCE_EMP_ID; if (!$emp_id && !empty($_SESSION['warper_emp_id'])) $emp_id = (int)$_SESSION['warper_emp_id']; try{ if (!$emp_id) { $uc = cols($pdo,'users'); if (isset($uc['employee_id'])) { $st=$pdo->prepare(" SELECT cem.id FROM company_employee_master cem JOIN users u ON u.company_id=cem.company_id AND u.employee_id=cem.id WHERE u.id=? AND u.company_id=? AND cem.is_active=1 AND cem.department_id=22 LIMIT 1 "); $st->execute([$user_id,$company_id]); $emp_id=(int)$st->fetchColumn(); } } if (!$emp_id && $user_name!=='') { $st=$pdo->prepare(" SELECT id FROM company_employee_master WHERE company_id=? AND is_active=1 AND department_id=22 AND (name=? OR TRIM(LOWER(name))=TRIM(LOWER(?))) ORDER BY id DESC "); $st->execute([$company_id,$user_name,$user_name]); $rows=$st->fetchAll(PDO::FETCH_COLUMN); if (count($rows)===1) $emp_id=(int)$rows[0]; } } catch(Throwable $e){} /* If user picked from dropdown, store in session (no DB write) */ if ($_SERVER['REQUEST_METHOD']==='POST' && postv('_action')==='choose_emp') { $chosen = (int)postv('emp_choose',0); $ok = 0; try{ $st=$pdo->prepare("SELECT id FROM company_employee_master WHERE company_id=? AND id=? AND is_active=1 AND department_id=22"); $st->execute([$company_id,$chosen]); $ok=(int)$st->fetchColumn(); }catch(Throwable $e){} if ($ok>0) { $_SESSION['warper_emp_id']=$ok; $emp_id=$ok; } } /* =================== F) Quality list ===================== */ $qualities=[]; if ($has_qid) { $sql = $bq_has_tar ? "SELECT id,name,COALESCE(warping_rate,0) rate,COALESCE(tar,'') tar FROM beam_qualities WHERE company_id=? ORDER BY name" : "SELECT id,name,COALESCE(warping_rate,0) rate,COALESCE(pattern,'') tar FROM beam_qualities WHERE company_id=? ORDER BY name"; $q=$pdo->prepare($sql); $q->execute([$company_id]); $qualities=$q->fetchAll(PDO::FETCH_ASSOC); } /* =================== G) Dept 22 list (for chooser) from CEM ===================== */ $dept22=[]; try{ $st=$pdo->prepare("SELECT id,name FROM company_employee_master WHERE company_id=? AND is_active=1 AND department_id=22 ORDER BY name"); $st->execute([$company_id]); $dept22=$st->fetchAll(PDO::FETCH_ASSOC); }catch(Throwable $e){} /* =================== G0) uniq_series-aware “next beam no” ===================== */ function idx_cols(PDO $pdo, string $tbl, string $idx): array { try{ $st=$pdo->prepare("SELECT COLUMN_NAME FROM information_schema.statistics WHERE table_schema=DATABASE() AND table_name=? AND index_name=? ORDER BY SEQ_IN_INDEX"); $st->execute([$tbl,$idx]); return array_map(fn($r)=>strtolower($r['COLUMN_NAME']), $st->fetchAll(PDO::FETCH_ASSOC)); }catch(Throwable $e){ return []; } } /** Fallback helper (old style; date optional) */ function next_beam_no(PDO $pdo,$company_id,$emp_id,$date=null){ if(!$emp_id) return ''; $params=[$company_id,$emp_id]; $w="company_id=? AND employee_id=?"; if ($date){ $w.=" AND entry_date=?"; $params[]=$date; } try{ $st=$pdo->prepare("SELECT COALESCE(MAX(CAST(beam_no AS UNSIGNED)),0) FROM beam_entry WHERE $w"); $st->execute($params); return (string)((int)$st->fetchColumn()+1); }catch(Throwable $e){ return ''; } } /** Smart helper: series = uniq_series columns (except beam_no) */ function next_beam_no_smart(PDO $pdo, array $series_cols, array $scope): string { if (!$series_cols) return ''; $cols = array_map('strtolower',$series_cols); if (!in_array('beam_no',$cols,true)) return ''; $where=[]; $params=[]; foreach($cols as $c){ if ($c==='beam_no' || $c==='id') continue; if (array_key_exists($c,$scope) && $scope[$c] !== null && $scope[$c] !== '') { $where[]="`$c`=?"; $params[]=$scope[$c]; } } if (!$where) return ''; $sql="SELECT COALESCE(MAX(CAST(beam_no AS UNSIGNED)),0) FROM beam_entry WHERE ".implode(' AND ',$where); try{ $st=$pdo->prepare($sql); $st->execute($params); $last=(int)$st->fetchColumn(); return (string)($last+1); } catch(Throwable $e){ return ''; } } /* detect uniq_series once */ $uniq_series_cols = idx_cols($pdo,'beam_entry','uniq_series'); /* Convenience: compute next-by-date for this employee */ function compute_next_for_date(PDO $pdo, $company_id, $emp_id, $date, $uniq_series_cols, $has_beam_no){ if(!$has_beam_no || !$emp_id) return ''; $scope=['company_id'=>$company_id,'employee_id'=>$emp_id,'entry_date'=>$date]; $nb = next_beam_no_smart($pdo,$uniq_series_cols,$scope); if ($nb==='') $nb = next_beam_no($pdo,$company_id,$emp_id,null); return $nb ?: ''; } /* =================== H) Ajax: next beam no ===================== */ if (getv('ajax')==='next_beam_no') { header('Content-Type: application/json'); $entry_date = (string)getv('entry_date', date('Y-m-d')); $next = ''; if ($has_beam_no && $emp_id>0) { $next = compute_next_for_date($pdo,$company_id,$emp_id,$entry_date,$uniq_series_cols,$has_beam_no); } echo json_encode(['ok'=>true,'next_beam_no'=>$next]); exit; } /* =================== I) Prefills (default + sticky) ===================== */ $default_beam = compute_next_for_date($pdo,$company_id,$emp_id,date('Y-m-d'),$uniq_series_cols,$has_beam_no); $pref_entry_date = date('Y-m-d'); $pref_beam_no = $default_beam; $pref_taka = ''; $pref_qid = 0; $pref_tar = ''; /* If POST, keep sticky values initially (will override after successful save) */ if ($_SERVER['REQUEST_METHOD']==='POST') { $pref_entry_date = postv('entry_date', $pref_entry_date); $pref_beam_no = postv('beam_no', $pref_beam_no); $pref_taka = postv('taka', $pref_taka); $pref_qid = (int)postv('quality_id', $pref_qid); $pref_tar = postv('tar', $pref_tar); } /* =================== J) Save ===================== */ $msg=''; $err=''; if ($_SERVER['REQUEST_METHOD']==='POST' && postv('_action')==='save') { if ($emp_id<=0) { $err='Access denied (not dept 22)'; } $entry_date = postv('entry_date', date('Y-m-d')); /* ===== PATCH: allow ONLY today's date ===== */ $today = date('Y-m-d'); if ($entry_date !== $today) { $err = 'Sirf aaj ki date ki entry allowed hai.'; } $beam_no = $has_beam_no ? trim((string)postv('beam_no',$default_beam)) : null; $taka = (int)postv('taka',0); $meter = $has_meter ? (float)max(0,$taka*120) : 0.0; $tar = $has_tar ? (string)postv('tar','') : null; $qid = $has_qid ? (int)postv('quality_id',0) : 0; if (!$err) { if (!preg_match('/^\d{4}-\d{2}-\d{2}$/',$entry_date)) $err='Invalid date.'; elseif ($taka<0) $err='Taka must be positive.'; elseif ($has_qid && $qid<=0) $err='Quality required.'; elseif ($has_beam_no && $beam_no==='') $err='Beam No required.'; } if (!$err && $has_tar && $tar==='' && $has_qid && $qid>0) { try { $field = $bq_has_tar ? 'tar' : 'pattern'; $st=$pdo->prepare("SELECT COALESCE($field,'') FROM beam_qualities WHERE company_id=? AND id=?"); $st->execute([$company_id,$qid]); $tar=(string)$st->fetchColumn(); }catch(Throwable $e){} } if (!$err && $has_beam_no && $beam_no==='') { $beam_no = compute_next_for_date($pdo,$company_id,$emp_id,$entry_date,$uniq_series_cols,$has_beam_no); } if (!$err) { $cols=['company_id','employee_id','entry_date','taka']; $vals=[ $company_id,$emp_id,$entry_date,$taka ]; if ($has_beam_no){ $cols[]='beam_no'; $vals[]=$beam_no; } if ($has_meter){ $cols[]='meter'; $vals[]=$meter; } if ($has_tar){ $cols[]='tar'; $vals[]=$tar; } if ($has_qid){ $cols[]='quality_id'; $vals[]=$qid; } if ($has_created){ $cols[]='created_by'; $vals[]=$user_id; } $ph=rtrim(str_repeat('?,',count($cols)),','); $ins=$pdo->prepare("INSERT INTO beam_entry (".implode(',',$cols).") VALUES ($ph)"); try { $ins->execute($vals); $msg='Saved.'; /* ===== PATCH: also insert into company_beam_stock ===== */ try { $st = $pdo->prepare(" INSERT INTO company_beam_stock ( company_id, warp_date, beam_no, quality_id, beam_quality, beam_slot, taka, meter, tar, warper_id, beam_load_date, load_type, created_at, updated_at ) VALUES ( :company_id, :warp_date, :beam_no, :quality_id, :beam_quality, 'primary', :taka, :meter, :tar, :warper_id, :beam_load_date, 'stock', NOW(), NOW() ) "); $st->execute([ ':company_id' => $company_id, ':warp_date' => $entry_date, ':beam_no' => $beam_no, ':quality_id' => $qid, ':beam_quality' => $qid, ':taka' => $taka, ':meter' => $meter, ':tar' => $has_tar ? (string)$tar : '', ':warper_id' => $emp_id, ':beam_load_date' => $entry_date ]); } catch (PDOException $e) { // optional: log error, but DO NOT block beam_entry } /* -------- After SAVE: Auto-update next Beam No (same date) -------- */ $pref_entry_date = $entry_date; // keep same date $pref_qid = $qid; // keep same quality $pref_tar = $has_tar ? (string)$tar : ''; $pref_taka = ''; // clear taka $pref_beam_no = compute_next_for_date($pdo,$company_id,$emp_id,$entry_date,$uniq_series_cols,$has_beam_no); } catch (PDOException $e) { $dup = ($e->getCode()==='23000' && stripos($e->getMessage(),'uniq_series')!==false); if ($dup && $has_beam_no) { $beam_no = compute_next_for_date($pdo,$company_id,$emp_id,$entry_date,$uniq_series_cols,$has_beam_no); $vals=[ $company_id,$emp_id,$entry_date,$taka ]; if ($has_beam_no){ $vals[]=$beam_no; } if ($has_meter){ $vals[]=$meter; } if ($has_tar){ $vals[]=$tar; } if ($has_qid){ $vals[]=$qid; } if ($has_created){ $vals[]=$user_id; } $ins->execute($vals); $msg='Saved.'; /* After SAVE on duplicate: same behavior */ $pref_entry_date = $entry_date; $pref_qid = $qid; $pref_tar = $has_tar ? (string)$tar : ''; $pref_taka = ''; $pref_beam_no = compute_next_for_date($pdo,$company_id,$emp_id,$entry_date,$uniq_series_cols,$has_beam_no); } else { $err='Save failed.'; } } } } /* =================== K) Show entries (this emp only) ===================== */ $show = (postv('_action')==='show'); $list=[]; if ($show && $emp_id>0) { $sel = "be.entry_date, be.taka"; if ($has_beam_no) $sel .= ", be.beam_no"; if ($has_meter) $sel .= ", be.meter"; if ($has_tar) $sel .= ", be.tar"; if ($has_qid) $sel .= ", COALESCE(q.name,'') AS quality"; $sql = "SELECT $sel FROM beam_entry be"; if ($has_qid) $sql .= " LEFT JOIN beam_qualities q ON q.id=be.quality_id AND q.company_id=be.company_id"; $sql .= " WHERE be.company_id=? AND be.employee_id=? ORDER BY be.entry_date DESC, be.id DESC LIMIT 100"; $st=$pdo->prepare($sql); $st->execute([$company_id,$emp_id]); $list=$st->fetchAll(PDO::FETCH_ASSOC); } /* =================== L) HTML ===================== */ ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Warper Beam Entry</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <style> :root{--primary:#34A853;--bg:#F5FFF7;--secondary:#5F6368;--border:#e5e7eb;--r:14px;--shadow:0 8px 20px rgba(0,0,0,.08);--text:#202124} *{box-sizing:border-box} body{margin:0;background:var(--bg);color:var(--text);font:14px/1.45 system-ui,-apple-system,Segoe UI,Roboto,Arial} .wrap{max-width:820px;margin:16px auto;padding:16px} .card{background:#fff;border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow);padding:18px} .top{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px} a.link{color:#0b57d0;text-decoration:none} a.link:hover{text-decoration:underline} .ok{margin:10px 0;background:#ecfdf5;border:1px solid #a7f3d0;color:#065f46;padding:8px;border-radius:10px} .err{margin:10px 0;background:#fee2e2;border:1px solid #fecaca;color:#7f1d1d;padding:8px;border-radius:10px} label{display:block;margin:8px 0 6px;font-weight:600} input,select{width:100%;padding:10px;border:1px solid #d0d7de;border-radius:10px;background:#fff} .btn{padding:10px 16px;border:0;border-radius:10px;cursor:pointer;font-weight:600} .btn-pri{background:var(--primary);color:#fff} .btn-sec{background:#f1f3f4} table{width:100%;border-collapse:collapse;margin-top:14px;background:#fff} th,td{padding:10px;border-bottom:1px solid #e5e7eb;text-align:left;font-size:13px} .right{text-align:right} .grid{display:grid;gap:14px;grid-template-columns:1fr 1fr} .grid .full{grid-column:1/-1} @media(max-width:640px){.grid{grid-template-columns:1fr}} </style> </head> <body> <div class="wrap"> <div class="top"> <a class="link" href="/erp/public/employee_portal.php">← Dashboard</a> <div style="color:#5F6368">Logged in: <?= h($user_name) ?></div> </div> <div class="card"> <h2>Warper Beam Entry</h2> <?php if($msg): ?><div class="ok" id="save_ok"><?= h($msg) ?></div><?php endif; ?> <?php if($err): ?><div class="err"><?= h($err) ?></div><?php endif; ?> <?php if($emp_id<=0): ?> <div class="err">You’re not linked to dept 22. Select your name (dept 22) to continue — this will be remembered only in session.</div> <form method="post" style="display:flex;gap:10px;flex-wrap:wrap;align-items:center"> <input type="hidden" name="_action" value="choose_emp"> <select name="emp_choose" required> <option value="">-- Dept 22 employees --</option> <?php foreach($dept22 as $e): ?> <option value="<?= (int)$e['id'] ?>"><?= h($e['name']) ?> (ID <?= (int)$e['id'] ?>)</option> <?php endforeach; ?> </select> <button class="btn btn-pri" type="submit">Continue</button> </form> <?php else: ?> <form method="post" autocomplete="off"> <input type="hidden" name="_action" value="save"> <input type="hidden" name="employee_id" value="<?= (int)$emp_id ?>"> <div class="grid"> <div><label>Warper</label><input type="text" value="<?= h($user_name) ?>" disabled></div> <?php if($has_beam_no): ?> <div><label>Beam No *</label><input type="text" name="beam_no" id="beam_no" value="<?= h($pref_beam_no) ?>" required></div> <?php endif; ?> <div><label>Create date</label><input type="date" name="entry_date" id="entry_date" value="<?= h($pref_entry_date) ?>" required></div> <div><label>Taka *</label><input id="taka" type="number" name="taka" min="0" step="1" value="<?= h($pref_taka) ?>" required></div> <?php if($has_qid): ?> <div><label>Quality</label> <select id="quality" name="quality_id" required> <option value="">-- Select --</option> <?php foreach($qualities as $q): ?> <option value="<?= (int)$q['id'] ?>" data-tar="<?= h($q['tar']) ?>" <?= ((int)$q['id']===(int)$pref_qid?'selected':'') ?>> <?= h($q['name']) ?> </option> <?php endforeach; ?> </select> </div> <?php endif; ?> <?php if($has_meter): ?> <div><label>Meter</label> <input id="meter" type="number" name="meter" value="<?= $pref_taka!=='' ? h((int)$pref_taka*120) : '' ?>" readonly> </div> <?php endif; ?> <?php if($has_tar): ?> <div class="full"><label>Tar</label><input id="tar" type="text" name="tar" value="<?= h($pref_tar) ?>"></div> <?php endif; ?> </div> <div style="margin-top:12px;display:flex;gap:10px;flex-wrap:wrap"> <button class="btn btn-pri" type="submit">Submit</button> <button class="btn btn-sec" type="reset">Reset</button> <button class="btn btn-sec" type="submit" name="_action" value="show" formnovalidate>Show Entries</button> </div> </form> <?php endif; ?> </div> <?php if($show && $emp_id>0): ?> <div class="card" style="margin-top:16px"> <h2>My Entries</h2> <table> <thead><tr> <th>Date</th> <?php if($has_beam_no): ?><th>Beam No</th><?php endif; ?> <th class="right">Taka</th> <?php if($has_meter): ?><th class="right">Meter</th><?php endif; ?> <?php if($has_qid): ?><th>Quality</th><?php endif; ?> <?php if($has_tar): ?><th>Tar</th><?php endif; ?> </tr></thead> <tbody> <?php if(!$list): ?> <tr><td colspan="6" style="color:#5F6368">No entries found.</td></tr> <?php else: foreach($list as $r): ?> <tr> <td><?= h($r['entry_date']) ?></td> <?php if($has_beam_no): ?><td><?= h($r['beam_no']) ?></td><?php endif; ?> <td class="right"><?= (int)$r['taka'] ?></td> <?php if($has_meter): ?><td class="right"><?= number_format((float)$r['meter'],2) ?></td><?php endif; ?> <?php if($has_qid): ?><td><?= h($r['quality'] ?? '') ?></td><?php endif; ?> <?php if($has_tar): ?><td><?= h($r['tar'] ?? '') ?></td><?php endif; ?> </tr> <?php endforeach; endif; ?> </tbody> </table> </div> <?php endif; ?> </div> <script> (function(){ const taka=document.getElementById('taka'), meter=document.getElementById('meter'); if(taka&&meter){ const r=()=>{const t=parseInt(taka.value||'0',10)||0; meter.value=t?String(t*120):'';}; taka.addEventListener('input',r); } const q=document.getElementById('quality'), tar=document.getElementById('tar'); if(q&&tar){ const f=()=>{const o=q.options[q.selectedIndex]; tar.value=(o&&o.dataset&&o.dataset.tar)?o.dataset.tar:''}; q.addEventListener('change',f); if(q.value){ f(); } } const d=document.getElementById('entry_date'), b=document.getElementById('beam_no'); async function upd(){ if(!d||!b) return; try{ const res=await fetch(location.pathname+'?ajax=next_beam_no&entry_date='+encodeURIComponent(d.value)); const j=await res.json(); if(j&&j.ok){ b.value=j.next_beam_no||''; } }catch(e){} } if(d) d.addEventListener('change',upd); // If just saved, ensure we still fetch from server (double-safety) and focus Taka const saved=document.getElementById('save_ok'); if(saved){ upd(); if(taka){ try{ taka.focus(); taka.select(); }catch(e){} } } // If Beam No is empty on load, fetch one if(b && (!b.value||b.value==='')) setTimeout(upd,120); })(); </script> </body> </html>