Autosave: 20260217-031716

This commit is contained in:
Flatlogic Bot 2026-02-17 03:17:17 +00:00
parent 538d43cf29
commit d61da6f246

155
index.php
View File

@ -1110,9 +1110,22 @@ switch ($page) {
$where = ["1=1"];
$params = [];
if (!empty($_GET['search'])) {
$where[] = "(q.id LIKE ? OR c.name LIKE ?)";
$params[] = "%{$_GET['search']}%";
$params[] = "%{$_GET['search']}%";
$term = $_GET['search'];
$cleanTerm = str_ireplace(['QUO-', 'INV-'], '', $term);
$cleanTerm = ltrim($cleanTerm, '0');
$searchClauses = ["c.name LIKE ?"];
$params[] = "%$term%";
$searchClauses[] = "q.id LIKE ?";
$params[] = "%$term%";
if ($cleanTerm !== '' && $cleanTerm !== $term) {
$searchClauses[] = "q.id LIKE ?";
$params[] = "%$cleanTerm%";
}
$where[] = "(" . implode(" OR ", $searchClauses) . ")";
}
if (!empty($_GET['customer_id'])) {
$where[] = "q.customer_id = ?";
@ -1151,9 +1164,22 @@ switch ($page) {
$params = [$type];
if (!empty($_GET['search'])) {
$where[] = "(v.id LIKE ? OR c.name LIKE ?)";
$params[] = "%{$_GET['search']}%";
$params[] = "%{$_GET['search']}%";
$term = $_GET['search'];
$cleanTerm = str_ireplace(['INV-', 'QUO-'], '', $term);
$cleanTerm = ltrim($cleanTerm, '0');
$searchClauses = ["c.name LIKE ?"];
$params[] = "%$term%";
$searchClauses[] = "v.id LIKE ?";
$params[] = "%$term%";
if ($cleanTerm !== '' && $cleanTerm !== $term) {
$searchClauses[] = "v.id LIKE ?";
$params[] = "%$cleanTerm%";
}
$where[] = "(" . implode(" OR ", $searchClauses) . ")";
}
if (!empty($_GET['customer_id'])) {
@ -3613,53 +3639,6 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
};
document.addEventListener('DOMContentLoaded', function() {
const hasExpiryToggle = document.getElementById('hasExpiryToggle');
const expiryDateContainer = document.getElementById('expiryDateContainer');
const suggestSkuBtn = document.getElementById('suggestSkuBtn');
const skuInput = document.getElementById('skuInput');
if (suggestSkuBtn && skuInput) {
suggestSkuBtn.addEventListener('click', function() {
const sku = Math.floor(100000000000 + Math.random() * 900000000000).toString();
skuInput.value = sku;
});
}
// Toggle Expiry Date visibility
if (hasExpiryToggle && expiryDateContainer) {
hasExpiryToggle.addEventListener('change', function() {
expiryDateContainer.style.display = this.checked ? 'block' : 'none';
if (!this.checked) {
expiryDateContainer.querySelector('input').value = '';
}
});
}
// Status change logic for Paid Amount field
const togglePaidAmount = (statusId, containerId) => {
const statusEl = document.getElementById(statusId);
const containerEl = document.getElementById(containerId);
if (statusEl && containerEl) {
statusEl.addEventListener('change', function() {
if (this.value === 'partially_paid') {
containerEl.style.display = 'block';
} else {
containerEl.style.display = 'none';
}
});
}
};
togglePaidAmount('add_status', 'addPaidAmountContainer');
togglePaidAmount('edit_status', 'editPaidAmountContainer');
// Show receipt modal if needed
<?php if (isset($_SESSION['trigger_receipt_modal'])):
$rid = (int)$_SESSION['show_receipt_id'];
unset($_SESSION['trigger_receipt_modal']);
?>
showReceipt(<?= $rid ?>);
<?php endif; ?>
window.showReceipt = function(paymentId) {
fetch(`index.php?action=get_payment_details&payment_id=${paymentId}`)
.then(res => res.json())
@ -3726,6 +3705,54 @@ document.addEventListener('DOMContentLoaded', function() {
});
};
const hasExpiryToggle = document.getElementById('hasExpiryToggle');
const expiryDateContainer = document.getElementById('expiryDateContainer');
const suggestSkuBtn = document.getElementById('suggestSkuBtn');
const skuInput = document.getElementById('skuInput');
if (suggestSkuBtn && skuInput) {
suggestSkuBtn.addEventListener('click', function() {
const sku = Math.floor(100000000000 + Math.random() * 900000000000).toString();
skuInput.value = sku;
});
}
// Toggle Expiry Date visibility
if (hasExpiryToggle && expiryDateContainer) {
hasExpiryToggle.addEventListener('change', function() {
expiryDateContainer.style.display = this.checked ? 'block' : 'none';
if (!this.checked) {
expiryDateContainer.querySelector('input').value = '';
}
});
}
// Status change logic for Paid Amount field
const togglePaidAmount = (statusId, containerId) => {
const statusEl = document.getElementById(statusId);
const containerEl = document.getElementById(containerId);
if (statusEl && containerEl) {
statusEl.addEventListener('change', function() {
if (this.value === 'partially_paid') {
containerEl.style.display = 'block';
} else {
containerEl.style.display = 'none';
}
});
}
};
togglePaidAmount('add_status', 'addPaidAmountContainer');
togglePaidAmount('edit_status', 'editPaidAmountContainer');
// Show receipt modal if needed
<?php if (isset($_SESSION['trigger_receipt_modal'])):
$rid = (int)$_SESSION['show_receipt_id'];
unset($_SESSION['trigger_receipt_modal']);
?>
showReceipt(<?= $rid ?>);
<?php endif; ?>
document.querySelectorAll('.view-payments-btn').forEach(btn => {
btn.addEventListener('click', function() {
const invoiceId = this.getAttribute('data-id');
@ -3867,14 +3894,18 @@ document.addEventListener('DOMContentLoaded', function() {
clearTimeout(timeout);
const q = this.value.trim();
if (q.length < 1) {
suggestions.style.display = 'none';
if (suggestions) suggestions.style.display = 'none';
return;
}
timeout = setTimeout(() => {
fetch(`index.php?action=search_items&q=${encodeURIComponent(q)}`)
.then(res => res.json())
.then(res => {
if (!res.ok) throw new Error('Network response was not ok');
return res.json();
})
.then(data => {
if (!suggestions) return;
suggestions.innerHTML = '';
if (data.length > 0) {
data.forEach(item => {
@ -3894,12 +3925,16 @@ document.addEventListener('DOMContentLoaded', function() {
} else {
suggestions.style.display = 'none';
}
})
.catch(err => {
console.error('Search error:', err);
if (suggestions) suggestions.style.display = 'none';
});
}, 300);
});
document.addEventListener('click', function(e) {
if (!searchInput.contains(e.target) && !suggestions.contains(e.target)) {
if (suggestions && !searchInput.contains(e.target) && !suggestions.contains(e.target)) {
suggestions.style.display = 'none';
}
});
@ -4091,7 +4126,7 @@ document.addEventListener('DOMContentLoaded', function() {
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
<div class="position-relative">
<input type="text" id="productSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
<div id="searchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 1000;"></div>
<div id="searchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 2000;"></div>
</div>
</div>
</div>
@ -4191,7 +4226,7 @@ document.addEventListener('DOMContentLoaded', function() {
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
<div class="position-relative">
<input type="text" id="editProductSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
<div id="editSearchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 1000;"></div>
<div id="editSearchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 2000;"></div>
</div>
</div>
</div>
@ -4273,7 +4308,7 @@ document.addEventListener('DOMContentLoaded', function() {
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
<div class="position-relative">
<input type="text" id="quotProductSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
<div id="quotSearchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 1000;"></div>
<div id="quotSearchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 2000;"></div>
</div>
</div>
</div>
@ -4366,7 +4401,7 @@ document.addEventListener('DOMContentLoaded', function() {
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
<div class="position-relative">
<input type="text" id="editQuotProductSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
<div id="editQuotSearchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 1000;"></div>
<div id="editQuotSearchSuggestions" class="list-group position-absolute w-100 shadow-sm" style="display: none; z-index: 2000;"></div>
</div>
</div>
</div>