39728-vm/stock.php
2026-04-19 10:09:23 +00:00

581 lines
28 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once __DIR__ . '/includes/app.php';
$user = require_permission('stock', 'show');
$pageTitle = tr('المخزون', 'Stock');
$activeNav = 'stock';
$dbError = null;
// Handle AJAX actions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
header('Content-Type: application/json');
$pdo = db();
if ($_POST['action'] === 'save') {
try {
$sku = $_POST['sku'] ?? '';
$name = $_POST['name'] ?? '';
$price = (float)($_POST['price'] ?? 0);
$cost_price = (float)($_POST['cost_price'] ?? 0);
$base_stock = (int)($_POST['base_stock'] ?? 0);
$vat = (float)($_POST['vat'] ?? get_setting('vat_percentage', 5));
$category_id = !empty($_POST['category_id']) ? (int)$_POST['category_id'] : null;
$supplier_id = !empty($_POST['supplier_id']) ? (int)$_POST['supplier_id'] : null;
$unit_id = !empty($_POST['unit_id']) ? (int)$_POST['unit_id'] : null;
if (!$sku || !$name) {
echo json_encode(['success' => false, 'error' => 'Missing SKU or Name']);
exit;
}
$image_url = $_POST['existing_image_url'] ?? null;
if (isset($_FILES['picture']) && $_FILES['picture']['error'] === UPLOAD_ERR_OK) {
$uploadDir = __DIR__ . '/assets/images/items/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0775, true);
}
$ext = pathinfo($_FILES['picture']['name'], PATHINFO_EXTENSION);
$filename = time() . '_' . rand(1000, 9999) . '.' . $ext;
if (move_uploaded_file($_FILES['picture']['tmp_name'], $uploadDir . $filename)) {
$image_url = 'assets/images/items/' . $filename;
}
}
$stmt = $pdo->prepare('SELECT id FROM items WHERE sku = ?');
$stmt->execute([$sku]);
$existing = $stmt->fetch();
if (isset($_POST['original_sku']) && $_POST['original_sku'] !== '') {
$orig_sku = $_POST['original_sku'];
if ($existing && $existing['id'] != ($pdo->query("SELECT id FROM items WHERE sku = " . $pdo->quote($orig_sku))->fetchColumn() ?: -1)) {
echo json_encode(['success' => false, 'error' => 'SKU already exists']);
exit;
}
$sql = "UPDATE items SET sku=?, name=?, price=?, cost_price=?, base_stock=?, vat=?, category_id=?, supplier_id=?, unit_id=? " . ($image_url ? ", image_url=?" : "") . " WHERE sku=?";
$params = [$sku, $name, $price, $cost_price, $base_stock, $vat, $category_id, $supplier_id, $unit_id];
if ($image_url) {
$params[] = $image_url;
}
$params[] = $orig_sku;
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
} else {
if ($existing) {
echo json_encode(['success' => false, 'error' => 'SKU already exists']);
exit;
}
$stmt = $pdo->prepare("INSERT INTO items (sku, name, price, cost_price, base_stock, vat, category_id, supplier_id, unit_id, image_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$sku, $name, $price, $cost_price, $base_stock, $vat, $category_id, $supplier_id, $unit_id, $image_url]);
}
echo json_encode(['success' => true]);
exit;
} catch (Throwable $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
exit;
}
}
if ($_POST['action'] === 'delete') {
try {
$sku = $_POST['sku'] ?? '';
if (!$sku) {
echo json_encode(['success' => false, 'error' => 'Missing SKU']);
exit;
}
$stmt = $pdo->prepare('DELETE FROM items WHERE sku = ?');
$stmt->execute([$sku]);
echo json_encode(['success' => true]);
exit;
} catch (Throwable $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
exit;
}
}
}
$allStock = [];
try {
$allStock = stock_snapshot();
} catch (Throwable $e) {
$dbError = $e->getMessage();
}
$categories = [];
$suppliers = [];
try {
$pdo = db();
$categories = $pdo->query('SELECT id, name_ar, name_en FROM categories ORDER BY name_ar ASC')->fetchAll();
$suppliers = $pdo->query('SELECT id, name FROM suppliers ORDER BY name ASC')->fetchAll();
$units = $pdo->query('SELECT id, name_ar, name_en FROM units ORDER BY name_ar ASC')->fetchAll();
} catch (Throwable $e) {
// Ignore if not present
}
// Search and filter logic
$search = $_GET['q'] ?? '';
$catFilter = $_GET['category'] ?? '';
$supFilter = $_GET['supplier'] ?? '';
$filteredStock = [];
if (empty($dbError)) {
$lowerSearch = strtolower($search);
foreach ($allStock as $key => $row) {
$matchSearch = !$search || str_contains(strtolower((string)$row['sku']), $lowerSearch) || str_contains(strtolower((string)$row['name']), $lowerSearch);
$matchCat = !$catFilter || (isset($row['category_id']) && $row['category_id'] == $catFilter);
$matchSup = !$supFilter || (isset($row['supplier_id']) && $row['supplier_id'] == $supFilter);
if ($matchSearch && $matchCat && $matchSup) {
$filteredStock[$key] = $row;
}
}
}
// Pagination logic
$page = max(1, (int)($_GET['p'] ?? 1));
$limit = 10;
$total = count($filteredStock);
$totalPages = max(1, ceil($total / $limit));
$offset = ($page - 1) * $limit;
$stockRows = array_slice($filteredStock, $offset, $limit, true);
require __DIR__ . '/includes/header.php';
?>
<section class="surface-card mb-4">
<div class="row g-4 align-items-center mb-3">
<div class="col-lg-8">
<h3 class="h5 mb-1"><i class="bi bi-box-seam me-2"></i><?= h(tr('قائمة الأصناف والمخزون', 'Items & Stock List')) ?></h3>
<p class="text-muted mb-0"><?= h(tr('إدارة الأصناف وجرد المخزون.', 'Manage items and inventory.')) ?></p>
</div>
<div class="col-lg-4 text-lg-end">
<button type="button" class="btn btn-secondary shadow-sm me-2" onclick="printBulkLabels()">
<i class="bi bi-upc-scan"></i> <?= h(tr('طباعة ملصقات', 'Print Labels')) ?>
</button>
<button type="button" class="btn btn-primary shadow-sm" onclick="openItemModal()">
<i class="bi bi-plus-lg"></i> <?= h(tr('إضافة صنف', 'Add Item')) ?>
</button>
</div>
</div>
<form class="mb-4" method="GET" action="stock.php">
<div class="row g-2">
<div class="col-md-4">
<div class="input-group">
<input type="text" name="q" id="searchInput" class="form-control" placeholder="<?= h(tr('بحث برمز الصنف أو الاسم...', 'Search by SKU or name...')) ?>" value="<?= h($search) ?>" autocomplete="off">
<button class="btn btn-outline-secondary bg-white" type="button" id="clearSearchBtn" style="<?= empty($search) ? 'display: none;' : '' ?>" title="<?= h(tr('مسح البحث', 'Clear Search')) ?>">
<i class="bi bi-x-lg"></i>
</button>
</div>
</div>
<div class="col-md-3">
<select name="category" class="form-select">
<option value=""><?= h(tr('الكل (التصنيف)', 'All Categories')) ?></option>
<?php foreach($categories as $cat): ?>
<option value="<?= h($cat['id']) ?>" <?= ($catFilter == $cat['id']) ? 'selected' : '' ?>><?= h(current_lang() === 'ar' ? $cat['name_ar'] : $cat['name_en']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-3">
<select name="supplier" class="form-select">
<option value=""><?= h(tr('الكل (المورد)', 'All Suppliers')) ?></option>
<?php foreach($suppliers as $sup): ?>
<option value="<?= h($sup['id']) ?>" <?= ($supFilter == $sup['id']) ? 'selected' : '' ?>><?= h($sup['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-2">
<button class="btn btn-primary w-100 shadow-sm" type="submit">
<i class="bi bi-funnel"></i> <?= h(tr('تصفية', 'Filter')) ?>
</button>
</div>
</div>
</form>
</section>
<section class="surface-card">
<?php if ($dbError): ?>
<div class="alert alert-warning"><?= h($dbError) ?></div>
<?php else: ?>
<div class="table-responsive shadow-sm" style="border-radius: 12px; overflow: hidden; border: 1px solid rgba(0,0,0,0.05);">
<table class="table table-hover align-middle mb-0 text-center" style="background-color: #fff;">
<thead style="background: linear-gradient(90deg, #0d6efd, #0dcaf0);">
<tr>
<th width="40" class="text-white border-0 py-3 fw-semibold bg-transparent">
<input class="form-check-input" type="checkbox" id="selectAllCheckbox" onclick="toggleAllCheckboxes(this)">
</th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent">SKU</th>
<th width="70" class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('صورة', 'Pic')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent text-start"><?= h(tr('الصنف', 'Product')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('السعر', 'Price')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('التكلفة', 'Cost')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('افتتاحي', 'Opening')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('مباع', 'Sold')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('متاح', 'Available')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent"><?= h(tr('التنبيه', 'Signal')) ?></th>
<th class="text-white border-0 py-3 fw-semibold bg-transparent text-end pe-4"><?= h(tr('إجراءات', 'Actions')) ?></th>
</tr>
</thead>
<tbody class="border-top-0">
<?php if(empty($stockRows)): ?>
<tr><td colspan="11" class="text-center text-muted py-5"><i class="bi bi-inbox fs-1 d-block text-black-50 mb-2"></i> <?= h(tr('لا توجد بيانات', 'No data found')) ?></td></tr>
<?php endif; ?>
<?php foreach ($stockRows as $row): ?>
<tr style="transition: all 0.2s ease;">
<td>
<input class="form-check-input item-checkbox" type="checkbox" value="<?= h($row['sku']) ?>">
</td>
<td class="text-secondary"><?= h($row['sku']) ?></td>
<td>
<?php if (!empty($row['image_url'])): ?>
<img src="<?= h($row['image_url']) ?>" alt="pic" class="img-thumbnail p-0 shadow-sm" style="width: 45px; height: 45px; object-fit: cover; border-radius: 10px;">
<?php else: ?>
<div class="bg-light text-muted d-flex align-items-center justify-content-center shadow-sm mx-auto" style="width: 45px; height: 45px; border-radius: 10px; font-size: 1rem;">
<i class="bi bi-box-seam"></i>
</div>
<?php endif; ?>
</td>
<td class="fw-bold text-start text-dark"><?= h($row['name']) ?></td>
<td><span class="badge bg-light text-dark border px-2 py-1"><?= h(currency($row['price'])) ?></span></td>
<td><span class="badge bg-light text-secondary border px-2 py-1"><?= h(currency($row['cost_price'] ?? 0)) ?></span></td>
<td class="text-secondary"><?= h((string) $row['base_stock']) ?></td>
<td class="text-secondary"><?= h((string) $row['sold']) ?></td>
<td class="fw-bold text-primary fs-6"><?= h((string) $row['available']) ?></td>
<td>
<?php if ($row['available'] <= 12): ?>
<span class="badge bg-warning bg-opacity-25 text-dark px-3 py-2 rounded-pill"><i class="bi bi-exclamation-triangle me-1"></i> <?= h(tr('منخفض', 'Low')) ?></span>
<?php else: ?>
<span class="badge bg-success bg-opacity-10 text-success px-3 py-2 rounded-pill border border-success border-opacity-25"><i class="bi bi-check2-circle me-1"></i> <?= h(tr('مستقر', 'Stable')) ?></span>
<?php endif; ?>
</td>
<td class="text-end pe-3">
<button class="btn btn-sm btn-outline-primary rounded-circle shadow-sm" style="width: 34px; height: 34px; padding: 0;" onclick="openItemModal('<?= h($row['sku']) ?>', '<?= h(addslashes($row['name'])) ?>', '<?= h($row['price']) ?>', '<?= h($row['cost_price'] ?? 0) ?>', '<?= h($row['base_stock']) ?>', '<?= h($row['vat'] ?? get_setting('vat_percentage', 5)) ?>', '<?= h($row['category_id'] ?? '') ?>', '<?= h($row['supplier_id'] ?? '') ?>', '<?= h($row['unit_id'] ?? '') ?>', '<?= h($row['image_url'] ?? '') ?>')" data-bs-toggle="tooltip" title="<?= h(tr('تعديل', 'Edit')) ?>">
<i class="bi bi-pencil"></i>
</button>
<a href="print_labels.php?sku=<?= urlencode($row['sku']) ?>" class="btn btn-sm btn-outline-secondary rounded-circle shadow-sm ms-1" style="width: 34px; height: 34px; padding: 0; line-height: 32px;" data-bs-toggle="tooltip" title="<?= h(tr('طباعة ملصق', 'Print Label')) ?>">
<i class="bi bi-printer"></i>
</a>
<button class="btn btn-sm btn-outline-danger rounded-circle shadow-sm ms-1" style="width: 34px; height: 34px; padding: 0;" onclick="deleteItem('<?= h(addslashes($row['sku'])) ?>')" data-bs-toggle="tooltip" title="<?= h(tr('حذف', 'Delete')) ?>">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php if ($totalPages > 1): ?>
<nav class="mt-4">
<ul class="pagination justify-content-center mb-0">
<?php for($i=1; $i<=$totalPages; $i++): ?>
<li class="page-item <?= $i === $page ? 'active' : '' ?>">
<a class="page-link" href="<?= h(url_for('stock.php', ['p' => $i, 'q' => $search, 'category' => $catFilter, 'supplier' => $supFilter])) ?>"><?= $i ?></a>
</li>
<?php endfor; ?>
</ul>
</nav>
<?php endif; ?>
<?php endif; ?>
</section>
<!-- Item Modal -->
<div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form onsubmit="handleItemSubmit(event)" id="itemForm">
<div class="modal-header bg-primary text-white ">
<h5 class="modal-title" id="itemModalLabel"><?= h(tr('إضافة / تعديل صنف', 'Add / Edit Item')) ?></h5>
<button type="button" class="btn-close btn-close-white " data-bs-dismiss="modal" aria-label="Close" ></button>
</div>
<div class="modal-body">
<input type="hidden" id="item_original_sku">
<input type="hidden" id="item_existing_image_url">
<div class="row">
<div class="col-12 mb-3 text-center">
<label class="form-label d-block text-start"><?= h(tr('صورة الصنف', 'Item Picture')) ?></label>
<input type="file" class="form-control" id="item_picture" accept="image/*">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('رمز الصنف (SKU)', 'SKU')) ?></label>
<div class="input-group">
<input type="text" class="form-control" id="item_sku" required maxlength="15">
<button type="button" class="btn btn-outline-secondary" onclick="suggestSKU()" title="<?= h(tr('اقتراح رمز', 'Suggest SKU')) ?>">
<i class="bi bi-arrow-clockwise"></i>
</button>
</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('اسم الصنف', 'Product Name')) ?></label>
<input type="text" class="form-control" id="item_name" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('السعر', 'Price')) ?></label>
<input type="number" step="0.001" class="form-control" id="item_price" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('التكلفة', 'Cost Price')) ?></label>
<input type="number" step="0.001" class="form-control" id="item_cost_price" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('الرصيد الافتتاحي', 'Opening Stock')) ?></label>
<input type="number" class="form-control" id="item_base_stock" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('الضريبة (VAT %)', 'VAT %')) ?></label>
<input type="number" step="0.001" class="form-control" id="item_vat" value="<?= h(get_setting('vat_percentage', 5)) ?>" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('التصنيف', 'Category')) ?></label>
<select class="form-select" id="item_category">
<option value=""><?= h(tr('-- اختر التصنيف --', '-- Select Category --')) ?></option>
<?php foreach($categories as $cat): ?>
<option value="<?= h($cat['id']) ?>"><?= h(current_lang() === 'ar' ? $cat['name_ar'] : $cat['name_en']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(tr('المورد', 'Supplier')) ?></label>
<select class="form-select" id="item_supplier">
<option value=""><?= h(tr('-- اختر المورد --', '-- Select Supplier --')) ?></option>
<?php foreach($suppliers as $sup): ?>
<option value="<?= h($sup['id']) ?>"><?= h($sup['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-12 mb-3">
<label class="form-label"><?= h(tr('الوحدة', 'Unit')) ?></label>
<select class="form-select" id="item_unit">
<option value=""><?= h(tr('-- اختر الوحدة --', '-- Select Unit --')) ?></option>
<?php foreach($units as $unit): ?>
<option value="<?= h($unit['id']) ?>"><?= h(current_lang() === 'ar' ? $unit['name_ar'] : $unit['name_en']) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?= h(tr('إلغاء', 'Cancel')) ?></button>
<button type="submit" class="btn btn-primary" id="saveItemBtn">
<i class="bi bi-save me-1"></i> <?= h(tr('حفظ التغييرات', 'Save Changes')) ?>
</button>
</div>
</form>
</div>
</div>
</div>
<script>
const existingSkus = <?= json_encode(array_values(array_unique(array_map('strval', array_column($allStock, 'sku'))))) ?>;
function suggestSKU() {
let newSku;
do {
newSku = Math.floor(10000000 + Math.random() * 90000000).toString().substring(0, 8);
} while (existingSkus.includes(newSku));
document.getElementById('item_sku').value = newSku;
}
let itemModalObj = null;
document.addEventListener('DOMContentLoaded', function () {
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
});
itemModalObj = new bootstrap.Modal(document.getElementById('itemModal'));
const searchInput = document.getElementById('searchInput');
const clearSearchBtn = document.getElementById('clearSearchBtn');
let searchTimeout;
if (searchInput) {
if (searchInput.value.length > 0) {
searchInput.focus();
const valLen = searchInput.value.length;
searchInput.setSelectionRange(valLen, valLen);
}
searchInput.addEventListener('input', function() {
const val = this.value;
if (clearSearchBtn) {
clearSearchBtn.style.display = val.length > 0 ? 'block' : 'none';
}
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
const trimmed = val.trim();
if (trimmed.length >= 2 || trimmed.length === 0) {
this.closest('form').submit();
}
}, 600);
});
}
if (clearSearchBtn) {
clearSearchBtn.addEventListener('click', function() {
if (searchInput) {
searchInput.value = '';
searchInput.closest('form').submit();
}
});
}
});
function openItemModal(sku = '', name = '', price = '', cost_price = '', base_stock = '', vat = '<?= h(get_setting('vat_percentage', 5)) ?>', category_id = '', supplier_id = '', unit_id = '', image_url = '') {
document.getElementById('item_original_sku').value = sku;
document.getElementById('item_existing_image_url').value = image_url;
document.getElementById('item_sku').value = sku;
document.getElementById('item_name').value = name;
document.getElementById('item_price').value = price;
document.getElementById('item_cost_price').value = cost_price;
document.getElementById('item_base_stock').value = base_stock;
document.getElementById('item_vat').value = vat;
document.getElementById('item_category').value = category_id;
document.getElementById('item_supplier').value = supplier_id;
document.getElementById('item_unit').value = unit_id;
// Remove old image preview if any
const oldPreview = document.getElementById('image_preview');
if (oldPreview) oldPreview.remove();
if (image_url) {
const preview = document.createElement('img');
preview.id = 'image_preview';
preview.src = image_url;
preview.style.maxHeight = '100px';
preview.className = 'mt-2 rounded shadow-sm border';
document.getElementById('item_picture').parentElement.appendChild(preview);
}
document.getElementById('item_picture').value = '';
itemModalObj.show();
}
async function handleItemSubmit(e) {
e.preventDefault();
const btn = document.getElementById('saveItemBtn');
const originalText = btn.innerHTML;
btn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>';
btn.disabled = true;
const formData = new FormData();
formData.append('action', 'save');
formData.append('original_sku', document.getElementById('item_original_sku').value);
formData.append('sku', document.getElementById('item_sku').value);
formData.append('name', document.getElementById('item_name').value);
formData.append('price', document.getElementById('item_price').value);
formData.append('cost_price', document.getElementById('item_cost_price').value);
formData.append('base_stock', document.getElementById('item_base_stock').value);
formData.append('vat', document.getElementById('item_vat').value);
formData.append('category_id', document.getElementById('item_category').value);
formData.append('supplier_id', document.getElementById('item_supplier').value);
formData.append('unit_id', document.getElementById('item_unit').value);
formData.append('existing_image_url', document.getElementById('item_existing_image_url').value);
const picInput = document.getElementById('item_picture');
if (picInput.files.length > 0) {
formData.append('picture', picInput.files[0]);
}
try {
const res = await fetch('stock.php', { method: 'POST', body: formData });
const json = await res.json();
if (json.success) {
itemModalObj.hide();
Swal.fire({
title: '<?= h(tr('تم الحفظ بنجاح', 'Successfully saved')) ?>',
icon: 'success',
showConfirmButton: false,
timer: 1500
}).then(() => location.reload());
} else {
Swal.fire('<?= h(tr('خطأ', 'Error')) ?>', json.error || '<?= h(tr('فشل الحفظ', 'Failed to save')) ?>', 'error');
}
} catch(err) {
Swal.fire('<?= h(tr('خطأ', 'Error')) ?>', '<?= h(tr('حدث خطأ في الاتصال', 'Network error')) ?>', 'error');
} finally {
btn.innerHTML = originalText;
btn.disabled = false;
}
}
function deleteItem(sku) {
Swal.fire({
title: '<?= h(tr('هل أنت متأكد؟', 'Are you sure?')) ?>',
text: '<?= h(tr('لن تتمكن من التراجع عن هذا!', "You won't be able to revert this!")) ?>',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#dc3545',
cancelButtonColor: '#6c757d',
confirmButtonText: '<?= h(tr('نعم، احذف', 'Yes, delete it!')) ?>',
cancelButtonText: '<?= h(tr('إلغاء', 'Cancel')) ?>'
}).then(async (result) => {
if (result.isConfirmed) {
try {
const formData = new FormData();
formData.append('action', 'delete');
formData.append('sku', sku);
const res = await fetch('stock.php', { method: 'POST', body: formData });
const json = await res.json();
if (json.success) {
Swal.fire({
title: '<?= h(tr('محذوف!', 'Deleted!')) ?>',
icon: 'success',
showConfirmButton: false,
timer: 1500
}).then(() => location.reload());
} else {
Swal.fire('<?= h(tr('خطأ', 'Error')) ?>', json.error || '<?= h(tr('فشل الحذف', 'Failed to delete')) ?>', 'error');
}
} catch(err) {
Swal.fire('<?= h(tr('خطأ', 'Error')) ?>', '<?= h(tr('حدث خطأ في الاتصال', 'Network error')) ?>', 'error');
}
}
});
}
function toggleAllCheckboxes(source) {
const checkboxes = document.querySelectorAll(".item-checkbox");
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = source.checked;
}
}
function printBulkLabels() {
const checkboxes = document.querySelectorAll(".item-checkbox:checked");
if (checkboxes.length === 0) {
Swal.fire('<?= h(tr("تنبيه", "Warning")) ?>', '<?= h(tr("يرجى تحديد صنف واحد على الأقل", "Please select at least one item")) ?>', 'warning inaly);
return;
}
let skus = [];
checkboxes.forEach((cb) => skus.push(cb.value));
const form = document.createElement('form');
form.method = 'POST';
form.action = 'print_labels.php';
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'skus';
input.value = skus.join(\",\");
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
</script>
<?php require __DIR__ . "/includes/footer.php"; ?>