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=?, base_stock=?, vat=?, category_id=?, supplier_id=? " . ($image_url ? ", image_url=?" : "") . " WHERE sku=?";
$params = [$sku, $name, $price, $base_stock, $vat, $category_id, $supplier_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, base_stock, vat, category_id, supplier_id, image_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$sku, $name, $price, $base_stock, $vat, $category_id, $supplier_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();
} 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';
?>
= h(tr('إدارة الأصناف وجرد المخزون.', 'Manage items and inventory.')) ?>= h(tr('قائمة الأصناف والمخزون', 'Items & Stock List')) ?>