« Back to History
va_send_entry.php
|
20260920_164915.php
Initial Domain Snapshot
Copy Code
<?php require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('va_send_entry'); $pdo = $ctx['pdo']; $company_id = (int)$ctx['company_id']; require_once __DIR__ . '/partials/header.php'; $msg = ''; $edit_id = $_GET['edit_id'] ?? null; /* ===== HELPERS ===== */ function get_financial_year($date) { $ts = strtotime($date); $y = (int)date('Y', $ts); $m = (int)date('m', $ts); return ($m >= 4) ? $y . '-' . substr(($y + 1), -2) : ($y - 1) . '-' . substr($y, -2); } function normalize_mgray_detail($raw) { if (empty($raw)) { return [[], null]; } $decoded = json_decode($raw, true); if (!is_array($decoded)) { return [[], null]; } $clean = []; foreach ($decoded as $row) { $gray_id = trim((string)($row['gray_id'] ?? '')); $pcs = trim((string)($row['pcs'] ?? '')); if ($gray_id === '' || $pcs === '' || !is_numeric($pcs) || (float)$pcs <= 0) { continue; } $num = (float)$pcs; $clean[] = [ 'gray_id' => $gray_id, 'pcs' => fmod($num, 1.0) == 0.0 ? (int)$num : $num ]; } return [$clean, $clean ? json_encode($clean, JSON_UNESCAPED_UNICODE) : null]; } /* ===== DATE FILTER ===== */ $from_date = $_GET['from_date'] ?? date('Y-m-01'); $to_date = $_GET['to_date'] ?? date('Y-m-d'); /* ===== DEFAULT VALUES & PERSISTENCE ===== */ $form = [ 'send_date' => $_POST['send_date'] ?? date('Y-m-d'), 'challan_no' => '', 'party_name' => '', 'quality' => '', 'grey_id' => '', 'mgray_detail' => $_POST['mgray_detail'] ?? '', 'pcs' => '', 'remark' => '' ]; /* ===== EDIT LOAD ===== */ if($edit_id && $_SERVER['REQUEST_METHOD'] !== 'POST'){ $stmt = $pdo->prepare("SELECT * FROM va_send_entry WHERE id=:id AND company_id=:cid"); $stmt->execute([':id'=>$edit_id, ':cid'=>$company_id]); $res = $stmt->fetch(PDO::FETCH_ASSOC); if($res) $form = $res; } /* ===== SAVE / UPDATE ===== */ if($_SERVER['REQUEST_METHOD']==='POST'){ try { $send_date = $_POST['send_date']; $fy = get_financial_year($send_date); [$mgray_rows, $mgray_detail_json] = normalize_mgray_detail($_POST['mgray_detail'] ?? ''); $total_pcs = is_numeric($_POST['pcs'] ?? null) ? (float)$_POST['pcs'] : 0; if (!empty($mgray_rows)) { $total_pcs = array_sum(array_map(fn($row) => (float)$row['pcs'], $mgray_rows)); } $total_pcs = fmod($total_pcs, 1.0) == 0.0 ? (int)$total_pcs : $total_pcs; if(!empty($_POST['id'])){ // UPDATE $stmt = $pdo->prepare(" UPDATE va_send_entry SET send_date=:dt, financial_year=:fy, challan_no=:ch, party_name=:party, quality=:q, grey_id=:gid, mgray_detail=:mgd, pcs=:pcs, remark=:rm WHERE id=:id AND company_id=:cid "); $stmt->execute([ ':dt'=>$send_date, ':fy'=>$fy, ':ch'=>$_POST['challan_no'], ':party'=>$_POST['party_name'], ':q'=>$_POST['quality'], ':gid'=>$_POST['grey_id'], ':mgd'=>$mgray_detail_json, ':pcs'=>$total_pcs, ':rm'=>$_POST['remark'], ':id'=>$_POST['id'], ':cid'=>$company_id ]); $msg = "Updated Successfully"; require_once __DIR__ . '/helpers/activity_helper.php'; log_activity([ 'activity_type' => 'entry', 'module_name' => 'va_send_entry', 'action_name' => 'update_save', 'activity_note' => "Challan: {$_POST['challan_no']}, Party: {$_POST['party_name']}, Quality: {$_POST['quality']}, Grey ID: {$_POST['grey_id']}, PCS: $total_pcs", 'reference_id' => (int)$_POST['id'], ]); } else { // INSERT $stmt = $pdo->prepare(" INSERT INTO va_send_entry (company_id, send_date, financial_year, challan_no, party_name, quality, grey_id, mgray_detail, pcs, remark) VALUES (:cid,:dt,:fy,:ch,:party,:q,:gid,:mgd,:pcs,:rm) "); $stmt->execute([ ':cid'=>$company_id, ':dt'=>$send_date, ':fy'=>$fy, ':ch'=>$_POST['challan_no'], ':party'=>$_POST['party_name'], ':q'=>$_POST['quality'], ':gid'=>$_POST['grey_id'], ':mgd'=>$mgray_detail_json, ':pcs'=>$total_pcs, ':rm'=>$_POST['remark'] ]); $msg = "Saved Successfully"; require_once __DIR__ . '/helpers/activity_helper.php'; log_activity([ 'activity_type' => 'entry', 'module_name' => 'va_send_entry', 'action_name' => 'add_save', 'activity_note' => "Challan: {$_POST['challan_no']}, Party: {$_POST['party_name']}, Quality: {$_POST['quality']}, Grey ID: {$_POST['grey_id']}, PCS: $total_pcs", 'reference_id' => null, ]); $form['challan_no'] = $form['party_name'] = $form['quality'] = $form['grey_id'] = $form['mgray_detail'] = $form['pcs'] = $form['remark'] = ''; } } catch(PDOException $e){ $msg = "Error: " . $e->getMessage(); } } /* ===== MASTER DATA ===== */ $parties = $pdo->prepare("SELECT party_name FROM job_work_party_master WHERE company_id=:cid AND is_active=1"); $parties->execute([':cid'=>$company_id]); $parties = $parties->fetchAll(PDO::FETCH_COLUMN); $qualities = $pdo->prepare("SELECT id, quality_name FROM fabric_quality_master WHERE company_id=:cid"); $qualities->execute([':cid'=>$company_id]); $qualities = $qualities->fetchAll(PDO::FETCH_ASSOC); /* ===== LIST ===== */ $list = $pdo->prepare(" SELECT v.*, q.quality_name FROM va_send_entry v LEFT JOIN fabric_quality_master q ON q.id=v.quality WHERE v.company_id=:cid AND v.send_date BETWEEN :f AND :t ORDER BY v.id DESC "); $list->execute([':cid'=>$company_id, ':f'=>$from_date, ':t'=>$to_date]); $data = $list->fetchAll(PDO::FETCH_ASSOC); ?> <link href="/erp/public/assets/select2.min.css" rel="stylesheet" /> <style> /* Select2 Bootstrap standard heights visual parity fix */ .select2-container .select2-selection--single { height: 38px !important; border: 1px solid #dee2e6 !important; } .select2-container--default .select2-selection--single .select2-selection__rendered { line-height: 36px !important; color: #212529 !important; padding-left: 12px !important; } .select2-container--default .select2-selection--single .select2-selection__arrow { height: 36px !important; } </style> <div class="container mt-4"> <div class="card p-3 mb-3 border-0 shadow-sm"> <form method="get" class="row g-2"> <div class="col-md-3"> <input type="date" name="from_date" value="<?= $from_date ?>" class="form-control"> </div> <div class="col-md-3"> <input type="date" name="to_date" value="<?= $to_date ?>" class="form-control"> </div> <div class="col-md-2"> <button class="btn btn-dark w-100">Filter</button> </div> </form> </div> <div class="card p-4 mb-3 border-0 shadow-sm"> <h5 class="mb-4 text-primary fw-bold"><?= $edit_id ? 'Edit VA Send Entry' : 'New VA Send Entry' ?></h5> <?php if($msg): ?> <div class="alert alert-info py-2 small"><?= htmlspecialchars($msg) ?></div> <?php endif; ?> <form method="post" class="row g-3"> <input type="hidden" name="id" value="<?= $form['id'] ?? '' ?>"> <div class="col-md-2"> <label class="small fw-bold">Date</label> <input type="date" name="send_date" value="<?= $form['send_date'] ?>" class="form-control" required> </div> <div class="col-md-2"> <label class="small fw-bold">Challan No</label> <input type="text" name="challan_no" value="<?= $form['challan_no'] ?>" class="form-control" required> </div> <div class="col-md-3"> <label class="small fw-bold">Party Name</label> <select name="party_name" class="form-select select2-party" required> <option value="">Select Party</option> <?php foreach($parties as $p): ?> <option value="<?= htmlspecialchars($p) ?>" <?= $form['party_name']==$p?'selected':'' ?>><?= htmlspecialchars($p) ?></option> <?php endforeach; ?> </select> </div> <div class="col-md-3"> <label class="small fw-bold">Quality</label> <select name="quality" class="form-select select2-quality" required> <option value="">Select Quality</option> <?php foreach($qualities as $q): ?> <option value="<?= $q['id'] ?>" <?= $form['quality']==$q['id']?'selected':'' ?>> <?= htmlspecialchars($q['quality_name']) ?> </option> <?php endforeach; ?> </select> </div> <div class="col-md-2"> <label class="small fw-bold">PCS</label> <input type="number" step="0.01" name="pcs" id="total_pcs" value="<?= htmlspecialchars((string)$form['pcs']) ?>" class="form-control" required> </div> <div class="col-md-2"> <label class="small fw-bold">Grey ID (Opt.)</label> <input type="text" name="grey_id" value="<?= $form['grey_id'] ?>" class="form-control" placeholder="ID"> </div> <div class="col-md-4"> <label class="small fw-bold d-block">Multi Gray Detail</label> <input type="hidden" name="mgray_detail" id="mgray_detail" value="<?= htmlspecialchars((string)($form['mgray_detail'] ?? ''), ENT_QUOTES) ?>"> <button type="button" class="btn btn-outline-primary w-100" id="openMultiGrayModal"> Add Multi Gray ID </button> </div> <div class="col-md-4"> <label class="small fw-bold">Remark</label> <input type="text" name="remark" value="<?= $form['remark'] ?>" class="form-control"> </div> <div class="col-md-10"> <div id="multiGraySummary" class="border rounded bg-light p-2 small text-muted">No multi gray detail added.</div> </div> <div class="col-md-2 d-flex align-items-end"> <button class="btn <?= $edit_id ? 'btn-warning' : 'btn-primary' ?> w-100 fw-bold"> <?= $edit_id ? 'UPDATE' : 'SAVE' ?> </button> </div> </form> </div> <div class="card p-3 border-0 shadow-sm"> <h5 class="mb-3">Recent Records</h5> <div class="table-responsive"> <table class="table table-hover align-middle"> <thead class="table-light"> <tr> <th>Date</th> <th>Challan No</th> <th>Party</th> <th>Quality</th> <th>Grey ID & PCS Detail</th> <th>FY</th> <th class="text-end">Total PCS</th> <th class="text-center">Action</th> </tr> </thead> <tbody> <?php foreach($data as $r): ?> <tr> <td><?= date('d-m-y', strtotime($r['send_date'])) ?></td> <td class="fw-bold text-primary"><?= $r['challan_no'] ?></td> <td><?= htmlspecialchars($r['party_name']) ?></td> <td><?= htmlspecialchars($r['quality_name']) ?></td> <td> <?php $has_detail = false; if (!empty($r['mgray_detail'])) { $mgray = json_decode($r['mgray_detail'], true); if (is_array($mgray) && count($mgray) > 0) { $has_detail = true; echo '<div class="d-flex flex-wrap gap-1">'; foreach ($mgray as $item) { echo '<span class="badge bg-primary">ID: ' . htmlspecialchars($item['gray_id']) . ' | ' . htmlspecialchars($item['pcs']) . ' Pcs</span>'; } echo '</div>'; } } if (!$has_detail) { if (!empty($r['grey_id'])) { echo '<span class="badge bg-secondary">ID: ' . htmlspecialchars($r['grey_id']) . ' | ' . htmlspecialchars($r['pcs']) . ' Pcs</span>'; } else { echo '<span class="text-muted small">-</span>'; } } ?> </td> <td class="small text-muted"><?= $r['financial_year'] ?></td> <td class="text-end fw-bold"><?= $r['pcs'] ?></td> <td class="text-center"> <a href="?edit_id=<?= $r['id'] ?>&from_date=<?= $from_date ?>&to_date=<?= $to_date ?>" class="btn btn-sm btn-outline-warning"> Edit </a> </td> </tr> <?php endforeach; ?> </tbody> </table> </div> </div> </div> <div class="modal fade" id="multiGrayModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-lg modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Multi Gray Detail</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <div class="table-responsive"> <table class="table table-bordered align-middle mb-2"> <thead class="table-light"> <tr> <th style="width:45%">Gray ID</th> <th style="width:35%">PCS</th> <th style="width:20%" class="text-center">Remove</th> </tr> </thead> <tbody id="multiGrayRows"></tbody> </table> </div> <div class="d-flex justify-content-between align-items-center"> <button type="button" class="btn btn-sm btn-outline-secondary" id="addMultiGrayRow">Add Row</button> <div class="fw-bold text-primary">Total PCS: <span id="multiGrayTotal">0</span></div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-light" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-primary" id="saveMultiGrayDetail">Apply Detail</button> </div> </div> </div> </div> <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/@ttskch/select2-bootstrap4-theme@1.5.2/dist/select2-bootstrap4.min.css" rel="stylesheet" /> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script> <style> .select2-container--bootstrap4 .select2-selection { height: 38px !important; border: 1px solid #dee2e6 !important; display: flex; align-items: center; } .select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered { color: #212529 !important; padding-left: 12px !important; } </style> <script> $(document).ready(function() { if ($.fn.select2) { $('.select2-party').select2({ theme: 'bootstrap4', placeholder: 'Select Party', allowClear: true, width: '100%' }); $('.select2-quality').select2({ theme: 'bootstrap4', placeholder: 'Select Quality', allowClear: true, width: '100%' }); } }); window.addEventListener('load', function () { const hiddenInput = document.getElementById('mgray_detail'); const totalPcsInput = document.getElementById('total_pcs'); const summaryBox = document.getElementById('multiGraySummary'); const rowsWrap = document.getElementById('multiGrayRows'); const totalWrap = document.getElementById('multiGrayTotal'); const openBtn = document.getElementById('openMultiGrayModal'); const addRowBtn = document.getElementById('addMultiGrayRow'); const saveBtn = document.getElementById('saveMultiGrayDetail'); const modalEl = document.getElementById('multiGrayModal'); if (!hiddenInput || !totalPcsInput || !summaryBox || !rowsWrap || !modalEl || !openBtn || !addRowBtn || !saveBtn || typeof bootstrap === 'undefined') { return; } const modal = bootstrap.Modal.getOrCreateInstance(modalEl); function parseRows() { if (!hiddenInput.value.trim()) { return []; } try { const parsed = JSON.parse(hiddenInput.value); return Array.isArray(parsed) ? parsed : []; } catch (e) { return []; } } function addRow(grayId = '', pcs = '') { const tr = document.createElement('tr'); tr.innerHTML = ` <td><input type="text" class="form-control gray-id-input" value="${grayId}"></td> <td><input type="number" step="0.01" min="0" class="form-control pcs-input" value="${pcs}"></td> <td class="text-center"><button type="button" class="btn btn-sm btn-outline-danger remove-row">X</button></td> `; rowsWrap.appendChild(tr); } function loadRowsIntoModal() { rowsWrap.innerHTML = ''; const rows = parseRows(); if (rows.length) { rows.forEach(row => addRow(row.gray_id || '', row.pcs || '')); } else { addRow(); } updateModalTotal(); } function collectRows() { const rows = []; rowsWrap.querySelectorAll('tr').forEach(tr => { const grayId = tr.querySelector('.gray-id-input')?.value.trim() || ''; const pcs = tr.querySelector('.pcs-input')?.value.trim() || ''; if (grayId !== '' && pcs !== '' && !isNaN(pcs) && Number(pcs) > 0) { rows.push({ gray_id: grayId, pcs: Number(pcs) % 1 === 0 ? Number.parseInt(pcs, 10) : Number(pcs) }); } }); return rows; } function updateModalTotal() { const total = collectRows().reduce((sum, row) => sum + Number(row.pcs || 0), 0); totalWrap.textContent = total; } function renderSummary() { const rows = parseRows(); if (!rows.length) { summaryBox.innerHTML = 'No multi gray detail added.'; return; } const total = rows.reduce((sum, row) => sum + Number(row.pcs || 0), 0); totalPcsInput.value = total; let html = '<div class="fw-bold text-success mb-1">Linked Gray Details</div><div class="d-flex flex-wrap gap-2">'; rows.forEach(row => { html += `<span class="badge bg-primary">Gray ID: ${row.gray_id} | PCS: ${row.pcs}</span>`; }); html += `</div><div class="mt-2 fw-bold">Total PCS: ${total}</div>`; summaryBox.innerHTML = html; } openBtn.addEventListener('click', function () { loadRowsIntoModal(); modal.show(); }); addRowBtn.addEventListener('click', function () { addRow(); }); rowsWrap.addEventListener('input', function (e) { if (e.target.classList.contains('pcs-input') || e.target.classList.contains('gray-id-input')) { updateModalTotal(); } }); rowsWrap.addEventListener('click', function (e) { if (e.target.classList.contains('remove-row')) { e.target.closest('tr')?.remove(); if (!rowsWrap.querySelector('tr')) { addRow(); } updateModalTotal(); } }); saveBtn.addEventListener('click', function () { const rows = collectRows(); hiddenInput.value = rows.length ? JSON.stringify(rows) : ''; if (rows.length) { const total = rows.reduce((sum, row) => sum + Number(row.pcs || 0), 0); totalPcsInput.value = total; } renderSummary(); modal.hide(); }); renderSummary(); }); </script> <?php require_once __DIR__ . '/partials/footer.php'; ?>