« Back to History
folding_entry_mob.php
|
20260722_120325.php
Initial Domain Snapshot
Copy Code
<?php // ========================================================== // File: /erp/folding_entry_mob.php // Simple mobile folding entry form, full width, large font, no header // Latest entry always shows on top (ORDER BY id DESC) // ========================================================== require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('folding_entry_mob'); $pdo = $ctx['pdo'] ?? null; $company_id = (int)($ctx['company_id'] ?? 0); $user_id = (int)($ctx['user']['id'] ?? 0); require_once __DIR__ . '/helpers/activity_helper.php'; if (session_status() === PHP_SESSION_NONE) session_start(); if (empty($_SESSION['csrf_token'])) $_SESSION['csrf_token'] = bin2hex(random_bytes(24)); $csrf_token = $_SESSION['csrf_token']; function e($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function fmt_num($v){ if ($v === null || $v === '') return ''; // remove trailing .00 if present if (is_numeric($v)) { if ((float)$v == (int)$v) return (string)(int)$v; return rtrim(rtrim((string)$v, '0'), '.'); } // fallback return (string)$v; } $folders = []; $khatas = []; $qualities = []; if ($pdo) { try { $sql = "SELECT id, name AS folder_name FROM company_employee_master WHERE company_id = :cid AND department_id = 24 AND designation_id = 9 ORDER BY name"; $stmt = $pdo->prepare($sql); $stmt->execute([':cid' => $company_id]); $folders = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($folders)) { $sql2 = "SELECT id, operation_name AS folder_name FROM company_machine_master WHERE company_id = :cid AND (department_name LIKE '%Folding%' OR operation_name LIKE '%Folder%') ORDER BY operation_name"; $stmt2 = $pdo->prepare($sql2); $stmt2->execute([':cid' => $company_id]); $folders = $stmt2->fetchAll(PDO::FETCH_ASSOC); } if (empty($folders)) { $sql3 = "SELECT id, name AS folder_name FROM company_employee_master WHERE company_id = :cid AND designation_name LIKE '%Folder%' ORDER BY name"; $stmt3 = $pdo->prepare($sql3); $stmt3->execute([':cid' => $company_id]); $folders = $stmt3->fetchAll(PDO::FETCH_ASSOC); } } catch (Exception $ex) { $folders = []; } try { // fetch khatas with code (we will hide code in UI but keep server-side) $sql = "SELECT id, name AS khata_name, code FROM khatas WHERE company_id = :cid ORDER BY name"; $stmt = $pdo->prepare($sql); $stmt->execute([':cid' => $company_id]); $khatas = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $ex) { $khatas = []; } try { $sql = "SELECT id, quality_name FROM qualities WHERE company_id = :cid ORDER BY quality_name"; $stmt = $pdo->prepare($sql); $stmt->execute([':cid' => $company_id]); $qualities = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $ex) { $qualities = []; } } $khataCodeToId = []; foreach ($khatas as $k) { $code = strtolower(trim($k['code'] ?? '')); if ($code !== '') $khataCodeToId[$code] = (int)$k['id']; } $autoMap = []; if (isset($khataCodeToId['mst1'])) $autoMap['satish'] = $khataCodeToId['mst1']; if (isset($khataCodeToId['mst2a'])) $autoMap['raj kishor'] = $khataCodeToId['mst2a']; if (isset($khataCodeToId['mst2b'])) { $autoMap['grish'] = $khataCodeToId['mst2b']; $autoMap['greesh'] = $khataCodeToId['mst2b']; $autoMap['grish '] = $khataCodeToId['mst2b']; } // machine range mapping (add/adjust as needed) $machineRanges = [ 'mst1' => '1-40', 'mst2a' => '41-76', 'mst2b' => '77-116', // add more codes here if needed: 'code' => 'start-end' ]; $errors = []; $success = false; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $posted_csrf = $_POST['csrf_token'] ?? ''; if (!hash_equals($_SESSION['csrf_token'], (string)$posted_csrf)) $errors[] = 'Invalid request (CSRF).'; if (!$pdo) $errors[] = 'Database connection unavailable.'; $posted_company = (int)($_POST['company_id'] ?? 0); if ($posted_company !== $company_id) $errors[] = 'Company mismatch.'; $entry_date = trim($_POST['entry_date'] ?? ''); $folder_id = (int)($_POST['folder_id'] ?? 0); $khata_id = (int)($_POST['khata_id'] ?? 0); $quality_id = (int)($_POST['quality_id'] ?? 0); $total_taka = trim($_POST['total_taka'] ?? ''); $total_meter = trim($_POST['total_meter'] ?? ''); $total_saree = ($_POST['total_saree'] !== '') ? (int)$_POST['total_saree'] : null; $total_weight = trim($_POST['total_weight'] ?? ''); $remark = trim($_POST['remark'] ?? ''); if ($entry_date === '') $errors[] = 'Date required.'; if ($folder_id <= 0) $errors[] = 'Select folder.'; if ($khata_id <= 0) $errors[] = 'Select khata.'; if ($quality_id <= 0) $errors[] = 'Select quality.'; if (empty($errors)) { try { $chk = $pdo->prepare("SELECT COUNT(*) c FROM folding_entry WHERE company_id = :cid AND entry_date = :ed AND folder_id = :fid AND quality_id = :qid"); $chk->execute([':cid'=>$company_id, ':ed'=>$entry_date, ':fid'=>$folder_id, ':qid'=>$quality_id]); $c = (int)$chk->fetchColumn(); if ($c > 0) $errors[] = 'An entry already exists for this date, folder and quality.'; } catch (Exception $ex) { error_log("folding_entry uniqueness check failed: ".$ex->getMessage()); } } if (empty($errors)) { try { $pdo->beginTransaction(); $sql = "INSERT INTO folding_entry (company_id, entry_date, folder_id, khata_id, quality_id, total_taka, total_meter, total_saree, total_weight, remark, created_by, created_at) VALUES (:cid, :entry_date, :folder_id, :khata_id, :quality_id, :total_taka, :total_meter, :total_saree, :total_weight, :remark, :uid, NOW())"; $stmt = $pdo->prepare($sql); $stmt->execute([ ':cid' => $company_id, ':entry_date' => $entry_date, ':folder_id' => $folder_id, ':khata_id' => $khata_id, ':quality_id' => $quality_id, ':total_taka' => $total_taka !== '' ? $total_taka : null, ':total_meter' => $total_meter !== '' ? $total_meter : null, ':total_saree' => $total_saree, ':total_weight'=> $total_weight !== '' ? $total_weight : null, ':remark' => $remark !== '' ? $remark : null, ':uid' => $user_id ]); $pdo->commit(); activity_create('production', 'folding_entry_create', (int)$pdo->lastInsertId(), 'Created folding entry (mobile)'); $_SESSION['csrf_token'] = bin2hex(random_bytes(24)); header('Location: folding_entry_mob.php?saved=1'); exit; } catch (Exception $ex) { if ($pdo && $pdo->inTransaction()) $pdo->rollBack(); $errors[] = 'Save failed: ' . $ex->getMessage(); } } } $success = isset($_GET['saved']) && $_GET['saved'] == '1'; // Fetch entries; latest id always on top $entries = []; if ($pdo) { try { $stmt = $pdo->prepare(" SELECT fe.entry_date, ce.name AS folder_name, k.name AS khata_name, k.code AS khata_code, q.quality_name, fe.total_taka, fe.total_meter, fe.total_saree, fe.total_weight, fe.remark FROM folding_entry fe LEFT JOIN company_employee_master ce ON fe.folder_id = ce.id LEFT JOIN khatas k ON fe.khata_id = k.id LEFT JOIN qualities q ON fe.quality_id = q.id WHERE fe.company_id = :cid ORDER BY fe.id DESC LIMIT 100 "); $stmt->execute([':cid' => $company_id]); $entries = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $ex) { $entries = []; } } ?> <style> body { background: #fff !important; color: #222 !important; margin: 0; padding: 0; font-size: 40px !important; width: 100vw !important; min-height: 100vh; } .page-container { margin: 20px !important; padding: 0 !important; max-width: 100vw !important; box-sizing: border-box; } .erp-entry-form { padding: 0 !important; margin: 0 !important; background: none !important; border: none !important; box-shadow: none !important; border-radius: 0 !important; } .ef-row { margin: 0 0 26px 0 !important; /* increased spacing */ } .ef-col label { display: block; margin-bottom: 10px; font-weight: 500; color: #111; font-size: 34px; } .ef-col input, .ef-col select, .ef-col textarea { width: 100%; box-sizing: border-box; font-size: 48px !important; /* slightly larger for touch */ padding: 20px 12px !important; /* more inner whitespace */ border: 1px solid #ddd; border-radius: 8px; color: #222; background: #fafafa; margin: 0; } .btn-success { width: 100%; font-size: 48px !important; padding: 20px 0 !important; margin: 12px 0 0 0 !important; background: #18ab4e; color: #fff; border: none; border-radius: 8px; cursor: pointer; } .notice-danger, .notice-success { font-size: 20px; margin-top: 10px; } /* Table styling — respect form width, prevent overflow */ .table-wrap { width: 100%; overflow-x: auto; margin-top: 22px; } table#entryList { width: 100%; table-layout: fixed; /* force wrap within table width */ background: #fff; color: #222; border-collapse: collapse; } table#entryList th, table#entryList td { border: 1px solid #e0e0e0; padding: 8px; font-size: 30px; /* slightly smaller for table to fit */ text-align: left; word-break: break-word; white-space: normal; } table#entryList th { background: #f6f6f6; } @media (max-width:420px){ .ef-col input, .ef-col select, .ef-col textarea { font-size: 44px !important; padding:16px 10px !important; } table#entryList th, table#entryList td { font-size: 26px; padding:6px; } } </style> <div class="page-container"> <div class="erp-entry-form"> <?php if (!empty($errors)): ?> <div class="notice notice-danger"> <ul> <?php foreach ($errors as $err): ?> <li><?= e($err) ?></li> <?php endforeach; ?> </ul> </div> <?php endif; ?> <?php if ($success): ?> <div class="notice notice-success">Saved successfully.</div> <?php endif; ?> <form method="post" autocomplete="off" novalidate> <input type="hidden" name="csrf_token" value="<?= e($csrf_token) ?>"> <input type="hidden" name="company_id" value="<?= e($company_id) ?>"> <input type="hidden" name="created_by" value="<?= e($user_id) ?>"> <div class="ef-row"> <div class="ef-col"> <label for="entry_date">Date</label> <input id="entry_date" name="entry_date" type="date" required value="<?= e(date('Y-m-d')) ?>"> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="folder_id">Folder</label> <select id="folder_id" name="folder_id" required> <option value="">Select folder</option> <?php foreach ($folders as $f): ?> <option value="<?= e($f['id']) ?>"><?= e($f['folder_name'] ?? $f['name'] ?? '') ?></option> <?php endforeach; ?> </select> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="khata_id">Khata (range)</label> <select id="khata_id" name="khata_id" required> <option value="">Select khata</option> <?php foreach ($khatas as $k): $code = strtolower(trim($k['code'] ?? '')); $range = isset($machineRanges[$code]) ? ' ' . $machineRanges[$code] : ''; // show khata name + machine range; hide code $label = ($k['khata_name'] ?? $k['name'] ?? '') . $range; ?> <option value="<?= e($k['id']) ?>" data-code="<?= e($k['code']) ?>"><?= e($label) ?></option> <?php endforeach; ?> </select> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="quality_id">Quality</label> <select id="quality_id" name="quality_id" required> <option value="">Select quality</option> <?php foreach ($qualities as $q): ?> <option value="<?= e($q['id']) ?>"><?= e($q['quality_name'] ?? $q['name'] ?? '') ?></option> <?php endforeach; ?> </select> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="total_taka">Taka</label> <input id="total_taka" name="total_taka" type="number" inputmode="numeric" pattern="\d*" placeholder="0-99"> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="total_meter">Meter</label> <input id="total_meter" name="total_meter" type="number" inputmode="numeric" pattern="\d*"> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="total_saree">Saree</label> <input id="total_saree" name="total_saree" type="number" inputmode="numeric" pattern="\d*" min="0"> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="total_weight">Weight</label> <input id="total_weight" name="total_weight" type="number" inputmode="numeric" pattern="\d*"> </div> </div> <div class="ef-row"> <div class="ef-col"> <label for="remark">Remark</label> <textarea id="remark" name="remark" style="height:56px;"></textarea> </div> </div> <div class="ef-actions"> <button class="btn-success" type="submit">Submit</button> </div> </form> <h3 style="margin-top:28px; border-bottom:1px solid #bbb; padding-bottom:8px;">Existing Entries</h3> <?php if (empty($entries)): ?> <p>No entries found.</p> <?php else: ?> <div class="table-wrap"> <table id="entryList"> <thead> <tr> <th>Date</th> <th>Folder</th> <th>Machine Range</th> <th>Quality</th> <th>Taka</th> <th>Meter</th> <th>Saree</th> <th>Weight</th> <th>Remark</th> </tr> </thead> <tbody> <?php foreach ($entries as $row): $code = strtolower(trim($row['khata_code'] ?? '')); $range = isset($machineRanges[$code]) ? $machineRanges[$code] : ''; // format date as "24 Nov" $displayDate = ''; if (!empty($row['entry_date'])) { $dt = strtotime($row['entry_date']); if ($dt !== false) $displayDate = date('j M', $dt); } ?> <tr> <td><?= e($displayDate) ?></td> <td><?= e($row['folder_name']) ?></td> <td><?= e($range) ?></td> <td><?= e($row['quality_name']) ?></td> <td><?= e(fmt_num($row['total_taka'])) ?></td> <td><?= e(fmt_num($row['total_meter'])) ?></td> <td><?= e(fmt_num($row['total_saree'])) ?></td> <td><?= e(fmt_num($row['total_weight'])) ?></td> <td><?= e($row['remark']) ?></td> </tr> <?php endforeach; ?> </tbody> </table> </div> <?php endif; ?> </div> </div> <script> (function(){ const form = document.querySelector('form'); const btn = form.querySelector('button[type="submit"]'); // pass autoMap and machineRanges to JS const autoMap = <?= json_encode($autoMap, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP) ?> || {}; const machineRanges = <?= json_encode($machineRanges, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP) ?> || {}; const folderEl = document.getElementById('folder_id'); const khataEl = document.getElementById('khata_id'); function setKhataById(id) { if (!id) return; const opt = khataEl.querySelector('option[value="'+id+'"]'); if (opt) { khataEl.value = id; khataEl.dispatchEvent(new Event('change')); } } folderEl.addEventListener('change', function(){ const text = folderEl.options[folderEl.selectedIndex]?.text || ''; const key = (text || '').trim().toLowerCase(); if (key && autoMap[key]) { setKhataById(String(autoMap[key])); } }); // On khata change we keep server-rendered label; machine range available via dataset khataEl.addEventListener('change', function(){ const opt = khataEl.options[khataEl.selectedIndex]; if (!opt) return; // nothing to show here; machine range used in table only }); document.addEventListener('DOMContentLoaded', function(){ if (folderEl.value) folderEl.dispatchEvent(new Event('change')); }); form.addEventListener('submit', function(e){ const required = form.querySelectorAll('[required]'); for (let el of required){ if (!el.value){ e.preventDefault(); alert('Please fill: ' + (el.previousElementSibling ? el.previousElementSibling.textContent : el.name)); el.focus(); return false; } } btn.disabled = true; btn.textContent = "Saving..."; }); })(); </script> <?php require_once __DIR__ . '/partials/footer.php'; ?>