« Back to History
send_other_location.php
|
20260723_000646.php
Initial Domain Snapshot
Copy Code
<?php require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('parcel_send_multi'); $pdo = $ctx['pdo']; $COMPANY_ID = (int)$ctx['company_id']; $USER_ID = (int)$ctx['user']['id']; function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function buildOtherLocationRemark($locationName) { $locationName = trim(preg_replace('/\s+/', ' ', (string)$locationName)); return $locationName === '' ? null : 'Send From: ' . $locationName; } $pdo->exec("CREATE TABLE IF NOT EXISTS parcel_other_locations ( id BIGINT PRIMARY KEY AUTO_INCREMENT, company_id BIGINT NOT NULL, unit_name VARCHAR(150) NOT NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, created_by BIGINT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uniq_company_unit_name (company_id, unit_name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); $seedStmt = $pdo->prepare("\n INSERT INTO parcel_other_locations (company_id, unit_name, created_by)\n VALUES (?, ?, ?)\n ON DUPLICATE KEY UPDATE is_active = VALUES(is_active)\n"); $seedStmt->execute([$COMPANY_ID, 'Millenuam MKT', $USER_ID]); $msg = $err = ''; $selected_bills = array_values(array_filter(array_map('trim', (array)($_POST['bill_no'] ?? [])), static function ($billNo) { return $billNo !== ''; })); $selected_location_id = (int)($_POST['other_location_id'] ?? 0); $selected_bill_lookup = array_fill_keys($selected_bills, true); $billStmt = $pdo->prepare("\n SELECT DISTINCT bill_no\n FROM parcel_stock_in\n WHERE company_id = ? AND status = 'in'\n ORDER BY CAST(bill_no AS UNSIGNED) ASC, bill_no ASC\n"); $billStmt->execute([$COMPANY_ID]); $bill_list = $billStmt->fetchAll(PDO::FETCH_COLUMN); $locationStmt = $pdo->prepare("\n SELECT id, unit_name\n FROM parcel_other_locations\n WHERE company_id = ? AND is_active = 1\n ORDER BY unit_name ASC\n"); $locationStmt->execute([$COMPANY_ID]); $location_list = $locationStmt->fetchAll(PDO::FETCH_ASSOC); if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!$selected_bills || $selected_location_id <= 0) { $err = 'Kam se kam ek Bill No aur Other Location select karna required hai.'; } else { try { $pdo->beginTransaction(); $locationNameStmt = $pdo->prepare("\n SELECT unit_name\n FROM parcel_other_locations\n WHERE company_id = ? AND id = ? AND is_active = 1\n LIMIT 1\n "); $locationNameStmt->execute([$COMPANY_ID, $selected_location_id]); $selected_location = (string)$locationNameStmt->fetchColumn(); if ($selected_location === '') { throw new Exception('Selected other location valid nahi mila.'); } $deleteStmt = $pdo->prepare("DELETE FROM parcel_send_entry WHERE company_id = ? AND bill_no = ?"); $insertStmt = $pdo->prepare("\n INSERT INTO parcel_send_entry\n (company_id, bill_no, vehicle_no, send_date, remark, created_at, created_by)\n VALUES (?, ?, ?, CURDATE(), ?, NOW(), ?)\n "); $stockStmt = $pdo->prepare("\n UPDATE parcel_stock_in\n SET status = 'out'\n WHERE company_id = ? AND bill_no = ? AND status = 'in'\n "); $processedCount = 0; foreach ($selected_bills as $selected_bill) { $deleteStmt->execute([$COMPANY_ID, $selected_bill]); $insertStmt->execute([ $COMPANY_ID, $selected_bill, 'OTHER LOCATION', buildOtherLocationRemark($selected_location), $USER_ID, ]); $stockStmt->execute([$COMPANY_ID, $selected_bill]); if ($stockStmt->rowCount() < 1) { throw new Exception('Bill No ' . $selected_bill . ' stock me available nahi mila ya pehle hi out hai.'); } $processedCount++; } $pdo->commit(); $msg = $processedCount . ' parcel other location send mark ho gaye aur stock se out ho gaye.'; $selected_bills = []; $selected_location_id = 0; } catch (Exception $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } $err = $e->getMessage(); } } } require_once __DIR__ . '/partials/header.php'; ?> <div class="container py-3 py-md-4"> <div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3 mb-4"> <div> <h3 class="fw-bold mb-1"><i class="bi bi-box-arrow-up-right me-2"></i>Send Other Location</h3> <p class="text-muted small mb-0">Mobile par bill tap karke select karein, phir location choose karke submit karein.</p> </div> <a href="parcel_send_multi.php" class="btn btn-outline-secondary btn-sm">Back to Multi Send</a> </div> <?php if ($msg): ?> <div class="alert alert-success shadow-sm"><?= h($msg) ?></div> <?php endif; ?> <?php if ($err): ?> <div class="alert alert-danger shadow-sm"><?= h($err) ?></div> <?php endif; ?> <div class="card shadow-sm border-0 overflow-hidden"> <div class="card-body p-3 p-md-4"> <?php if (!$location_list): ?> <div class="alert alert-warning mb-0">Other location list available nahi hai.</div> <?php else: ?> <form method="post" class="row g-4" autocomplete="off"> <div class="col-12 col-lg-4 order-2 order-lg-1"> <label class="form-label fw-bold">Other Location</label> <select name="other_location_id" class="form-select form-select-lg" required> <option value="">Select Other Location</option> <?php foreach ($location_list as $location): ?> <option value="<?= (int)$location['id'] ?>" <?= $selected_location_id === (int)$location['id'] ? 'selected' : '' ?>> <?= h($location['unit_name']) ?> </option> <?php endforeach; ?> </select> <div class="card bg-light border-0 mt-3"> <div class="card-body p-3"> <div class="small text-muted mb-1">Selected Bills</div> <div class="fs-4 fw-bold" id="selectedBillCount"><?= count($selected_bills) ?></div> <div class="small text-muted">Tap on bill cards below. Desktop par bhi same UI rahegi.</div> </div> </div> <div class="d-grid mt-3"> <button type="submit" class="btn btn-primary btn-lg fw-bold">SEND OTHER LOCATION</button> </div> </div> <div class="col-12 col-lg-8 order-1 order-lg-2"> <div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-2 mb-3"> <label class="form-label fw-bold mb-0">Bill Selection</label> <div class="d-flex flex-wrap gap-2"> <button type="button" class="btn btn-outline-dark btn-sm" id="selectAllBillsBtn">Select All</button> <button type="button" class="btn btn-outline-secondary btn-sm" id="clearAllBillsBtn">Clear</button> </div> </div> <div class="input-group input-group-lg mb-3 shadow-sm"> <span class="input-group-text bg-white"><i class="bi bi-search"></i></span> <input type="text" class="form-control" id="billSearchInput" placeholder="Bill No search karein..."> </div> <div class="bill-grid" id="billSelectionGrid"> <?php foreach ($bill_list as $bill_no): ?> <?php $isChecked = isset($selected_bill_lookup[(string)$bill_no]); ?> <label class="bill-card card border-0 shadow-sm" data-bill-card data-bill-label="<?= h(strtolower((string)$bill_no)) ?>"> <div class="card-body d-flex align-items-center justify-content-between gap-3 p-3"> <div> <div class="small text-muted text-uppercase">Bill No</div> <div class="fw-bold fs-5"><?= h($bill_no) ?></div> </div> <div class="form-check m-0"> <input class="form-check-input bill-checkbox" type="checkbox" name="bill_no[]" value="<?= h($bill_no) ?>" <?= $isChecked ? 'checked' : '' ?> > </div> </div> </label> <?php endforeach; ?> </div> <div class="small text-muted mt-3" id="emptyBillState" <?= $bill_list ? 'hidden' : '' ?>>Pending bills available nahi hain.</div> </div> </form> <?php endif; ?> </div> </div> </div> <script> const billSearchInput = document.getElementById('billSearchInput'); const billCheckboxes = Array.from(document.querySelectorAll('.bill-checkbox')); const selectedBillCount = document.getElementById('selectedBillCount'); const emptyBillState = document.getElementById('emptyBillState'); function updateSelectedBillCount() { if (!selectedBillCount) { return; } const checkedCount = billCheckboxes.filter(function (checkbox) { return checkbox.checked; }).length; selectedBillCount.textContent = String(checkedCount); } function filterBillCards() { const query = (billSearchInput?.value || '').trim().toLowerCase(); let visibleCount = 0; document.querySelectorAll('[data-bill-card]').forEach(function (card) { const label = card.getAttribute('data-bill-label') || ''; const isVisible = query === '' || label.indexOf(query) !== -1; card.hidden = !isVisible; if (isVisible) { visibleCount += 1; } }); if (emptyBillState) { emptyBillState.hidden = visibleCount !== 0; if (visibleCount === 0) { emptyBillState.textContent = query === '' ? 'Pending bills available nahi hain.' : 'Search ke hisab se koi bill nahi mila.'; } } } document.getElementById('selectAllBillsBtn')?.addEventListener('click', function () { billCheckboxes.forEach(function (checkbox) { if (!checkbox.closest('[data-bill-card]').hidden) { checkbox.checked = true; } }); updateSelectedBillCount(); }); document.getElementById('clearAllBillsBtn')?.addEventListener('click', function () { billCheckboxes.forEach(function (checkbox) { checkbox.checked = false; }); updateSelectedBillCount(); }); billCheckboxes.forEach(function (checkbox) { checkbox.addEventListener('change', updateSelectedBillCount); }); billSearchInput?.addEventListener('input', filterBillCards); updateSelectedBillCount(); filterBillCards(); </script> <style> .bill-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.85rem; max-height: 65vh; overflow: auto; padding-right: 0.15rem; } .bill-card { cursor: pointer; background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%); transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; } .bill-card:hover { transform: translateY(-1px); box-shadow: 0 0.5rem 1rem rgba(15, 23, 42, 0.08); } .bill-card:has(.bill-checkbox:checked) { outline: 2px solid #0d6efd; background: linear-gradient(180deg, #eef5ff 0%, #dceafe 100%); } .bill-checkbox { width: 1.35rem; height: 1.35rem; } @media (max-width: 767.98px) { .bill-grid { grid-template-columns: 1fr; max-height: none; } } </style> <?php require_once __DIR__ . '/partials/footer.php'; ?>