Autosave: 20260217-031716
This commit is contained in:
parent
538d43cf29
commit
d61da6f246
155
index.php
155
index.php
@ -1110,9 +1110,22 @@ switch ($page) {
|
|||||||
$where = ["1=1"];
|
$where = ["1=1"];
|
||||||
$params = [];
|
$params = [];
|
||||||
if (!empty($_GET['search'])) {
|
if (!empty($_GET['search'])) {
|
||||||
$where[] = "(q.id LIKE ? OR c.name LIKE ?)";
|
$term = $_GET['search'];
|
||||||
$params[] = "%{$_GET['search']}%";
|
$cleanTerm = str_ireplace(['QUO-', 'INV-'], '', $term);
|
||||||
$params[] = "%{$_GET['search']}%";
|
$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'])) {
|
if (!empty($_GET['customer_id'])) {
|
||||||
$where[] = "q.customer_id = ?";
|
$where[] = "q.customer_id = ?";
|
||||||
@ -1151,9 +1164,22 @@ switch ($page) {
|
|||||||
$params = [$type];
|
$params = [$type];
|
||||||
|
|
||||||
if (!empty($_GET['search'])) {
|
if (!empty($_GET['search'])) {
|
||||||
$where[] = "(v.id LIKE ? OR c.name LIKE ?)";
|
$term = $_GET['search'];
|
||||||
$params[] = "%{$_GET['search']}%";
|
$cleanTerm = str_ireplace(['INV-', 'QUO-'], '', $term);
|
||||||
$params[] = "%{$_GET['search']}%";
|
$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'])) {
|
if (!empty($_GET['customer_id'])) {
|
||||||
@ -3613,53 +3639,6 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
|||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
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) {
|
window.showReceipt = function(paymentId) {
|
||||||
fetch(`index.php?action=get_payment_details&payment_id=${paymentId}`)
|
fetch(`index.php?action=get_payment_details&payment_id=${paymentId}`)
|
||||||
.then(res => res.json())
|
.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 => {
|
document.querySelectorAll('.view-payments-btn').forEach(btn => {
|
||||||
btn.addEventListener('click', function() {
|
btn.addEventListener('click', function() {
|
||||||
const invoiceId = this.getAttribute('data-id');
|
const invoiceId = this.getAttribute('data-id');
|
||||||
@ -3867,14 +3894,18 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
const q = this.value.trim();
|
const q = this.value.trim();
|
||||||
if (q.length < 1) {
|
if (q.length < 1) {
|
||||||
suggestions.style.display = 'none';
|
if (suggestions) suggestions.style.display = 'none';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
fetch(`index.php?action=search_items&q=${encodeURIComponent(q)}`)
|
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 => {
|
.then(data => {
|
||||||
|
if (!suggestions) return;
|
||||||
suggestions.innerHTML = '';
|
suggestions.innerHTML = '';
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
@ -3894,12 +3925,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
} else {
|
} else {
|
||||||
suggestions.style.display = 'none';
|
suggestions.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('Search error:', err);
|
||||||
|
if (suggestions) suggestions.style.display = 'none';
|
||||||
});
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('click', function(e) {
|
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';
|
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>
|
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<input type="text" id="productSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
|
<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>
|
</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>
|
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<input type="text" id="editProductSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
|
<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>
|
</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>
|
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<input type="text" id="quotProductSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
|
<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>
|
</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>
|
<label class="form-label fw-bold" data-en="Search Items" data-ar="بحث عن أصناف">Search Items</label>
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<input type="text" id="editQuotProductSearchInput" class="form-control" placeholder="Search by name or SKU..." autocomplete="off">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user