From eca10c44c770ea78608678bbbc5ef7b8cc32bac8 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 18 Mar 2026 18:40:01 +0000 Subject: [PATCH] separating stock --- check_nesting.php | 48 ----------- debug.log | 17 ++++ index.php | 213 ++++++++++++++++++---------------------------- post_debug.log | 13 +++ 4 files changed, 111 insertions(+), 180 deletions(-) delete mode 100644 check_nesting.php diff --git a/check_nesting.php b/check_nesting.php deleted file mode 100644 index 6eaee8a..0000000 --- a/check_nesting.php +++ /dev/null @@ -1,48 +0,0 @@ - $line) { - $line_num = $idx + 1; - - // Simple check for PHP tags - if (strpos($line, '') !== false) $in_php = false; - - // Alternative syntax checks - if (preg_match('/\bif\b\s*\(.*\)\s*:/', $line)) { - $stack[] = ['type' => 'if', 'line' => $line_num]; - } elseif (preg_match('/\belseif\b\s*\(.*\)\s*:/', $line)) { - // elseif is part of the current if block, so it doesn't change nesting level - } elseif (preg_match('/\belse\b\s*:/', $line)) { - // else is part of the current if block, so it doesn't change nesting level - } elseif (preg_match('/foreach\s*\(.*\)\s*:/', $line)) { - $stack[] = ['type' => 'foreach', 'line' => $line_num]; - } - if (strpos($line, 'endif;') !== false) { - if (empty($stack)) { - echo "Unexpected endif; at line $line_num\n"; - } else { - $last = array_pop($stack); - if ($last['type'] !== 'if') { - echo "Mismatched endif; at line $line_num (expected endforeach; for {$last['type']} at line {$last['line']})\n"; - } - } - } - if (strpos($line, 'endforeach;') !== false) { - if (empty($stack)) { - echo "Unexpected endforeach; at line $line_num\n"; - } else { - $last = array_pop($stack); - if ($last['type'] !== 'foreach') { - echo "Mismatched endforeach; at line $line_num (expected endif; for {$last['type']} at line {$last['line']})\n"; - } - } - } -} - -foreach ($stack as $unclosed) { - echo "Unclosed {$unclosed['type']} starting at line {$unclosed['line']}\n"; -} diff --git a/debug.log b/debug.log index 6fb40c6..23d579e 100644 --- a/debug.log +++ b/debug.log @@ -67,3 +67,20 @@ 2026-03-18 18:08:41 - Items case hit 2026-03-18 22:12:51 - Items case hit 2026-03-18 22:15:09 - Items case hit +2026-03-18 22:24:28 - Items case hit +2026-03-18 22:25:14 - Items case hit +2026-03-18 22:25:43 - Items case hit +2026-03-18 22:26:38 - Items case hit +2026-03-18 22:29:27 - Items case hit +2026-03-18 22:29:45 - Items case hit +2026-03-18 22:30:17 - Requesting AI. UUID: [e1f9b5b3-fcef-4c8d-87d2-8630b1f72491] CFG: {"base_url":"https:\/\/flatlogic.com","responses_path":"\/projects\/38471\/ai-request","project_id":"38471","project_uuid":"e1f9b5b3-fcef-4c8d-87d2-8630b1f72491","project_header":"Project-UUID","default_model":"gpt-4o-mini","timeout":30,"verify_tls":true} +2026-03-18 22:30:49 - Items case hit +2026-03-18 22:31:04 - Requesting AI. UUID: [e1f9b5b3-fcef-4c8d-87d2-8630b1f72491] CFG: {"base_url":"https:\/\/flatlogic.com","responses_path":"\/projects\/38471\/ai-request","project_id":"38471","project_uuid":"e1f9b5b3-fcef-4c8d-87d2-8630b1f72491","project_header":"Project-UUID","default_model":"gpt-4o-mini","timeout":30,"verify_tls":true} +2026-03-18 22:31:16 - Items case hit +2026-03-18 22:31:26 - Requesting AI. UUID: [e1f9b5b3-fcef-4c8d-87d2-8630b1f72491] CFG: {"base_url":"https:\/\/flatlogic.com","responses_path":"\/projects\/38471\/ai-request","project_id":"38471","project_uuid":"e1f9b5b3-fcef-4c8d-87d2-8630b1f72491","project_header":"Project-UUID","default_model":"gpt-4o-mini","timeout":30,"verify_tls":true} +2026-03-18 22:31:35 - Items case hit +2026-03-18 22:31:54 - Requesting AI. UUID: [e1f9b5b3-fcef-4c8d-87d2-8630b1f72491] CFG: {"base_url":"https:\/\/flatlogic.com","responses_path":"\/projects\/38471\/ai-request","project_id":"38471","project_uuid":"e1f9b5b3-fcef-4c8d-87d2-8630b1f72491","project_header":"Project-UUID","default_model":"gpt-4o-mini","timeout":30,"verify_tls":true} +2026-03-18 22:32:01 - Items case hit +2026-03-18 22:32:15 - Requesting AI. UUID: [e1f9b5b3-fcef-4c8d-87d2-8630b1f72491] CFG: {"base_url":"https:\/\/flatlogic.com","responses_path":"\/projects\/38471\/ai-request","project_id":"38471","project_uuid":"e1f9b5b3-fcef-4c8d-87d2-8630b1f72491","project_header":"Project-UUID","default_model":"gpt-4o-mini","timeout":30,"verify_tls":true} +2026-03-18 22:32:28 - Items case hit +2026-03-18 22:33:07 - Items case hit diff --git a/index.php b/index.php index 57a21ad..28ce68e 100644 --- a/index.php +++ b/index.php @@ -841,7 +841,11 @@ function getPromotionalPrice($item) { if (move_uploaded_file($_FILES['image']['tmp_name'], $filename)) $image_path = $filename; } $stmt = db()->prepare("INSERT INTO stock_items (name_en, name_ar, category_id, unit_id, supplier_id, sku, sale_price, purchase_price, stock_quantity, min_stock_level, image_path, vat_rate, expiry_date, is_promotion, promotion_start, promotion_end, promotion_percent) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - $stmt->execute([$name_en, $name_ar, $category_id, $unit_id, $supplier_id, $sku, $sale_price, $purchase_price, $stock_quantity, $min_stock_level, $image_path, $vat_rate, $expiry_date, $is_promotion, $promotion_start, $promotion_end, $promotion_percent]); + // Insert 0 for global stock, real stock goes to outlet_stock + $stmt->execute([$name_en, $name_ar, $category_id, $unit_id, $supplier_id, $sku, $sale_price, $purchase_price, 0, $min_stock_level, $image_path, $vat_rate, $expiry_date, $is_promotion, $promotion_start, $promotion_end, $promotion_percent]); + $new_item_id = db()->lastInsertId(); + $current_oid = current_outlet_id(); + db()->prepare("INSERT INTO outlet_stock (outlet_id, item_id, quantity) VALUES (?, ?, ?)")->execute([$current_oid, $new_item_id, $stock_quantity]); redirectWithMessage("Item added successfully!"); } @@ -863,8 +867,19 @@ function getPromotionalPrice($item) { $promotion_start = !empty($_POST['promotion_start']) ? $_POST['promotion_start'] : null; $promotion_end = !empty($_POST['promotion_end']) ? $_POST['promotion_end'] : null; $promotion_percent = (float)($_POST['promotion_percent'] ?? 0); - $stmt = db()->prepare("UPDATE stock_items SET name_en = ?, name_ar = ?, category_id = ?, unit_id = ?, supplier_id = ?, sku = ?, sale_price = ?, purchase_price = ?, stock_quantity = ?, min_stock_level = ?, vat_rate = ?, expiry_date = ?, is_promotion = ?, promotion_start = ?, promotion_end = ?, promotion_percent = ? WHERE id = ?"); - $stmt->execute([$name_en, $name_ar, $category_id, $unit_id, $supplier_id, $sku, $sale_price, $purchase_price, $stock_quantity, $min_stock_level, $vat_rate, $expiry_date, $is_promotion, $promotion_start, $promotion_end, $promotion_percent, $id]); + // Update stock_items (excluding stock_quantity) + $stmt = db()->prepare("UPDATE stock_items SET name_en = ?, name_ar = ?, category_id = ?, unit_id = ?, supplier_id = ?, sku = ?, sale_price = ?, purchase_price = ?, min_stock_level = ?, vat_rate = ?, expiry_date = ?, is_promotion = ?, promotion_start = ?, promotion_end = ?, promotion_percent = ? WHERE id = ?"); + $stmt->execute([$name_en, $name_ar, $category_id, $unit_id, $supplier_id, $sku, $sale_price, $purchase_price, $min_stock_level, $vat_rate, $expiry_date, $is_promotion, $promotion_start, $promotion_end, $promotion_percent, $id]); + + // Update outlet_stock + $current_oid = current_outlet_id(); + $check = db()->prepare("SELECT id FROM outlet_stock WHERE outlet_id = ? AND item_id = ?"); + $check->execute([$current_oid, $id]); + if ($check->fetch()) { + db()->prepare("UPDATE outlet_stock SET quantity = ? WHERE outlet_id = ? AND item_id = ?")->execute([$stock_quantity, $current_oid, $id]); + } else { + db()->prepare("INSERT INTO outlet_stock (outlet_id, item_id, quantity) VALUES (?, ?, ?)")->execute([$current_oid, $id, $stock_quantity]); + } if (isset($_FILES['image']) && $_FILES['image']['error'] === 0) { $ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION); $filename = 'uploads/item_' . $id . '_' . time() . '.' . $ext; @@ -1375,11 +1390,10 @@ function getPromotionalPrice($item) { # --- Unified Import Logic (Excel & CSV) --- if (isset($_POST['import_items'])) { error_log("Import items triggered."); - $count = 0; if (isset($_FILES['excel_file']) && $_FILES['excel_file']['error'] === 0) { $tmpPath = $_FILES['excel_file']['tmp_name']; $rows = []; - if ( $xlsx = SimpleXLSX::parse($tmpPath) ) { + if ( $xlsx = \Shuchkin\SimpleXLSX::parse($tmpPath) ) { $rows = $xlsx->rows(); } else { $handle = fopen($tmpPath, "r"); @@ -1403,12 +1417,31 @@ function getPromotionalPrice($item) { $check = db()->prepare("SELECT id FROM stock_items WHERE sku = ?"); $check->execute([$sku]); - if ($check->fetch()) { - db()->prepare("UPDATE stock_items SET name_en = ?, name_ar = ?, sale_price = ?, purchase_price = ?, stock_quantity = ?, vat_rate = ? WHERE sku = ?") - ->execute([$name_en, $name_ar, $sale_price, $purchase_price, $qty, $vat_rate, $sku]); + $exists = $check->fetch(PDO::FETCH_ASSOC); + $current_oid = current_outlet_id(); + + if ($exists) { + $item_id = $exists['id']; + // Update Item (excluding stock_quantity) + db()->prepare("UPDATE stock_items SET name_en = ?, name_ar = ?, sale_price = ?, purchase_price = ?, vat_rate = ? WHERE id = ?") + ->execute([$name_en, $name_ar, $sale_price, $purchase_price, $vat_rate, $item_id]); + + // Update Outlet Stock + $os_check = db()->prepare("SELECT id FROM outlet_stock WHERE outlet_id = ? AND item_id = ?"); + $os_check->execute([$current_oid, $item_id]); + if ($os_check->fetch()) { + db()->prepare("UPDATE outlet_stock SET quantity = ? WHERE outlet_id = ? AND item_id = ?")->execute([$qty, $current_oid, $item_id]); + } else { + db()->prepare("INSERT INTO outlet_stock (outlet_id, item_id, quantity) VALUES (?, ?, ?)")->execute([$current_oid, $item_id, $qty]); + } } else { + // Insert Item db()->prepare("INSERT INTO stock_items (sku, name_en, name_ar, sale_price, purchase_price, stock_quantity, vat_rate) VALUES (?, ?, ?, ?, ?, ?, ?)") - ->execute([$sku, $name_en, $name_ar, $sale_price, $purchase_price, $qty, $vat_rate]); + ->execute([$sku, $name_en, $name_ar, $sale_price, $purchase_price, 0, $vat_rate]); + $item_id = db()->lastInsertId(); + + // Insert Outlet Stock + db()->prepare("INSERT INTO outlet_stock (outlet_id, item_id, quantity) VALUES (?, ?, ?)")->execute([$current_oid, $item_id, $qty]); } $count++; } @@ -1424,7 +1457,7 @@ function getPromotionalPrice($item) { if (isset($_FILES['excel_file']) && $_FILES['excel_file']['error'] === 0) { $tmpPath = $_FILES['excel_file']['tmp_name']; $rows = []; - if ( $xlsx = SimpleXLSX::parse($tmpPath) ) { + if ( $xlsx = \Shuchkin\SimpleXLSX::parse($tmpPath) ) { $rows = $xlsx->rows(); } else { $handle = fopen($tmpPath, "r"); @@ -1457,7 +1490,7 @@ function getPromotionalPrice($item) { if (isset($_FILES['excel_file']) && $_FILES['excel_file']['error'] === 0) { $tmpPath = $_FILES['excel_file']['tmp_name']; $rows = []; - if ( $xlsx = SimpleXLSX::parse($tmpPath) ) { $rows = $xlsx->rows(); } + if ( $xlsx = \Shuchkin\SimpleXLSX::parse($tmpPath) ) { $rows = $xlsx->rows(); } else { $handle = fopen($tmpPath, "r"); while (($data = fgetcsv($handle)) !== FALSE) $rows[] = $data; @@ -1480,7 +1513,35 @@ function getPromotionalPrice($item) { if (isset($_POST['import_units'])) { $count = 0; - + if (isset($_FILES['excel_file']) && $_FILES['excel_file']['error'] === 0) { + $tmpPath = $_FILES['excel_file']['tmp_name']; + $rows = []; + if ( $xlsx = \Shuchkin\SimpleXLSX::parse($tmpPath) ) { $rows = $xlsx->rows(); } + else { + $handle = fopen($tmpPath, "r"); + $firstLine = fgets($handle); rewind($handle); + $sep = (substr_count($firstLine, ';') > substr_count($firstLine, ',')) ? ';' : ','; + $bom = fread($handle, 3); if ($bom !== "") rewind($handle); + while (($data = fgetcsv($handle, 0, $sep)) !== FALSE) $rows[] = $data; + fclose($handle); + } + if (isset($rows[0][0]) && (stripos($rows[0][0], 'name') !== false || stripos($rows[0][0], 'id') !== false)) array_shift($rows); + + foreach ($rows as $row) { + if (empty($row[0])) continue; + $name_en = trim((string)$row[0]); + $name_ar = trim((string)($row[1] ?? $name_en)); + $short_en = trim((string)($row[2] ?? '')); + $short_ar = trim((string)($row[3] ?? '')); + + db()->prepare("INSERT INTO stock_units (name_en, name_ar, short_en, short_ar) VALUES (?, ?, ?, ?)") + ->execute([$name_en, $name_ar, $short_en, $short_ar]); + $count++; + } + redirectWithMessage("Import units completed! $count processed.", "index.php?page=units"); + } + } + if (isset($_POST['add_expense_category'])) { $name_en = $_POST['name_en'] ?? ''; $name_ar = $_POST['name_ar'] ?? ''; @@ -1757,122 +1818,6 @@ function getPromotionalPrice($item) { $message = "Expense recorded!"; } - if (isset($_FILES['excel_file']) && $_FILES['excel_file']['error'] === 0) { - $tmpPath = $_FILES['excel_file']['tmp_name']; - error_log("File uploaded to: $tmpPath"); - $firstBytes = file_get_contents($tmpPath, false, null, 0, 4); - if ($firstBytes === "PK\x03\x04") { - $message = "Error: It looks like you uploaded an Excel (.xlsx) file. Please save it as CSV (UTF-8) and try again."; - } else { - // Check for BOM and skip it - if (substr($firstBytes, 0, 3) === "\xEF\xBB\xBF") { - $handle = fopen($tmpPath, "r"); - fseek($handle, 3); - } else { - $handle = fopen($tmpPath, "r"); - } - - $firstLine = fgets($handle); - rewind($handle); - if (substr($firstBytes, 0, 3) === "\xEF\xBB\xBF") fseek($handle, 3); - - error_log("First line of CSV: " . $firstLine); - - $seps = [",", ";", "\t", "|"]; - $sep = ","; - $maxCount = 0; - foreach ($seps as $s) { - $count = substr_count($firstLine, $s); - if ($count > $maxCount) { - $maxCount = $count; - $sep = $s; - } - } - error_log("Detected separator: '$sep' (count: $maxCount)"); - - // Try to detect if first line is header - $firstRow = fgetcsv($handle, 0, $sep); - $isHeader = true; - // If the first row's 4th or 5th columns are numeric, it's probably NOT a header - if (isset($firstRow[3]) && is_numeric(str_replace(',', '', trim($firstRow[3])))) $isHeader = false; - if (isset($firstRow[4]) && is_numeric(str_replace(',', '', trim($firstRow[4])))) $isHeader = false; - - if (!$isHeader) { - rewind($handle); - if (substr($firstBytes, 0, 3) === "\xEF\xBB\xBF") fseek($handle, 3); - error_log("No header detected, starting from first row."); - } else { - error_log("Header detected and skipped: " . print_r($firstRow, true)); - } - - $count = 0; $errors = 0; - while (($data = fgetcsv($handle, 0, $sep)) !== FALSE) { - if (count($data) < 2) continue; // Skip empty or single-column rows that aren't SKUs - if (empty($data[0]) && empty($data[1]) && empty($data[2])) continue; - try { - foreach ($data as &$val) { - if ($val === null) continue; - if (!mb_check_encoding($val, 'UTF-8')) { - $val = mb_convert_encoding($val, 'UTF-8', 'Windows-1252'); - } - $val = mb_convert_encoding($val, 'UTF-8', 'UTF-8'); - $val = trim($val); - } - - // Map: 0:sku, 1:name_en, 2:name_ar, 3:sale_price, 4:cost_price - $sku = substr(trim($data[0] ?? ''), 0, 100); - $name_en = $data[1] ?? ''; - $name_ar = $data[2] ?? ''; - $sale_price = str_replace(',', '', $data[3] ?? 0); - $purchase_price = str_replace(',', '', $data[4] ?? 0); - - if (empty($sku) && empty($name_en)) continue; - - $stmt = db()->prepare("INSERT INTO stock_items (sku, name_en, name_ar, sale_price, purchase_price) - VALUES (?, ?, ?, ?, ?) - ON DUPLICATE KEY UPDATE name_en=VALUES(name_en), name_ar=VALUES(name_ar), - sale_price=VALUES(sale_price), purchase_price=VALUES(purchase_price)"); - $stmt->execute([$sku, $name_en, $name_ar, (float)$sale_price, (float)$purchase_price]); - $count++; - } catch (Throwable $e) { - file_put_contents('import_debug.log', date('Y-m-d H:i:s') . " - Row error: " . $e->getMessage() . " Data: " . json_encode($data) . "\n", FILE_APPEND); - error_log("Import row error: " . $e->getMessage() . " Data: " . print_r($data, true)); - $errors++; - } - } - fclose($handle); - $message = "Import completed! $count items processed." . ($errors > 0 ? " ($errors rows skipped due to data errors.)" : ""); - error_log("Import finished. Processed: $count, Errors: $errors"); - } - } else { - $errCode = $_FILES['excel_file']['error'] ?? 'no file'; - error_log("File upload failed or missing. Error code: $errCode"); - $message = "Error: File upload failed. (Error code: $errCode)"; - } - } - - if (isset($_POST['add_expense_category'])) { - db()->prepare("INSERT INTO expense_categories (name_en, name_ar) VALUES (?, ?)")->execute([$_POST['name_en'] ?? '', $_POST['name_ar'] ?? '']); - $message = "Expense category added!"; - } - - if (isset($_POST['add_payment_method'])) { - db()->prepare("INSERT INTO payment_methods (name, type) VALUES (?, ?)")->execute([$_POST['name'] ?? '', $_POST['type'] ?? 'Cash']); - $message = "Payment method added!"; - } - - if (isset($_POST['delete_invoice'])) { - $id = (int)$_POST['id']; - $type = ($page === 'purchases') ? 'purchase' : 'sale'; - $table = ($type === 'purchase') ? 'purchases' : 'invoices'; - $item_table = ($type === 'purchase') ? 'purchase_items' : 'invoice_items'; - $fk_col = ($type === 'purchase') ? 'purchase_id' : 'invoice_id'; - - db()->prepare("DELETE FROM $table WHERE id = ?")->execute([$id]); - db()->prepare("DELETE FROM $item_table WHERE $fk_col = ?")->execute([$id]); - $message = ($type === 'purchase' ? "Purchase" : "Invoice") . " deleted!"; - } - if (isset($_POST['edit_invoice'])) { $db = db(); try { @@ -3162,8 +3107,10 @@ switch ($page) { $data['total_pages'] = ceil($total_records / $limit); $data['current_page'] = $page_num; - $stmt = db()->prepare("SELECT i.*, c.name_en as cat_en, c.name_ar as cat_ar, u.short_name_en as unit_en, u.short_name_ar as unit_ar, s.name as supplier_name + $oid = current_outlet_id(); + $stmt = db()->prepare("SELECT i.*, COALESCE(os.quantity, 0) as stock_quantity, c.name_en as cat_en, c.name_ar as cat_ar, u.short_name_en as unit_en, u.short_name_ar as unit_ar, s.name as supplier_name FROM stock_items i + LEFT JOIN outlet_stock os ON i.id = os.item_id AND os.outlet_id = $oid LEFT JOIN stock_categories c ON i.category_id = c.id LEFT JOIN stock_units u ON i.unit_id = u.id LEFT JOIN suppliers s ON i.supplier_id = s.id @@ -3596,12 +3543,14 @@ switch ($page) { $data['expiry_items'] = $stmt->fetchAll(); break; case 'low_stock_report': - $stmt = db()->prepare("SELECT i.*, c.name_en as cat_en, c.name_ar as cat_ar, s.name as supplier_name + $oid = current_outlet_id(); + $stmt = db()->prepare("SELECT i.*, COALESCE(os.quantity, 0) as stock_quantity, c.name_en as cat_en, c.name_ar as cat_ar, s.name as supplier_name FROM stock_items i + LEFT JOIN outlet_stock os ON i.id = os.item_id AND os.outlet_id = $oid LEFT JOIN stock_categories c ON i.category_id = c.id LEFT JOIN suppliers s ON i.supplier_id = s.id - WHERE i.stock_quantity <= i.min_stock_level - ORDER BY (i.min_stock_level - i.stock_quantity) DESC"); + WHERE COALESCE(os.quantity, 0) <= i.min_stock_level + ORDER BY (i.min_stock_level - COALESCE(os.quantity, 0)) DESC"); $stmt->execute(); $data['low_stock_items'] = $stmt->fetchAll(); break; diff --git a/post_debug.log b/post_debug.log index 0896934..3c00a42 100644 --- a/post_debug.log +++ b/post_debug.log @@ -80,3 +80,16 @@ 2026-03-18 14:09:15 - POST: {"action":"save_theme","theme":"default"} 2026-03-18 18:14:49 - POST: {"import_items":""} 2026-03-18 18:15:31 - POST: {"import_items":""} +2026-03-18 18:24:49 - POST: {"import_items":""} +2026-03-18 18:26:54 - POST: {"import_items":""} +2026-03-18 18:29:45 - POST: {"import_items":""} +2026-03-18 18:30:17 - POST: {"action":"translate","text":"LAMING RED KIDNEY BEANS ","target":"ar"} +2026-03-18 18:30:49 - POST: {"id":"62","name_en":"LAMING RED KIDNEY BEANS ","name_ar":"\u0641\u0627\u0635\u0648\u0644\u064a\u0627\u0621 \u062d\u0645\u0631\u0627\u0621 \u0643\u064a\u062f\u0646\u064a \u0644\u0627\u0645\u064a\u0646\u063a","sku":"000023071605","category_id":"3","unit_id":"4","supplier_id":"","sale_price":"0.25","purchase_price":"0.2","stock_quantity":"0","min_stock_level":"0","vat_rate":"5","promotion_start":"","promotion_end":"","promotion_percent":"0","edit_item":""} +2026-03-18 18:31:04 - POST: {"action":"translate","text":"LAMING PINEAPPLE 454G","target":"ar"} +2026-03-18 18:31:15 - POST: {"id":"61","name_en":"LAMING PINEAPPLE 454G","name_ar":"\u0623\u0646\u0627\u0646\u0627\u0633 \u0644\u0627\u0645\u0646\u062c 454\u063a","sku":"000023071599","category_id":"3","unit_id":"4","supplier_id":"","sale_price":"0.4","purchase_price":"0.346","stock_quantity":"0","min_stock_level":"0","vat_rate":"5","promotion_start":"","promotion_end":"","promotion_percent":"0","edit_item":""} +2026-03-18 18:31:26 - POST: {"action":"translate","text":"\u0644\u0627\u0645\u064a\u0646\u063a \u0641\u0637\u0631 \u0637\u0627\u0632\u062c \u0643\u0627\u0645\u0644425\u063a","target":"en"} +2026-03-18 18:31:34 - POST: {"id":"60","name_en":"Laming Whole Fresh Mushroom 425g","name_ar":"\u0644\u0627\u0645\u064a\u0646\u063a \u0641\u0637\u0631 \u0637\u0627\u0632\u062c \u0643\u0627\u0645\u0644425\u063a","sku":"000023071582","category_id":"3","unit_id":"4","supplier_id":"","sale_price":"0.55","purchase_price":"0.425","stock_quantity":"0","min_stock_level":"0","vat_rate":"0.00","promotion_start":"","promotion_end":"","promotion_percent":"0","edit_item":""} +2026-03-18 18:31:54 - POST: {"action":"translate","text":"LAMING FOUL MEDAMES 397G","target":"ar"} +2026-03-18 18:32:01 - POST: {"id":"59","name_en":"LAMING FOUL MEDAMES 397G","name_ar":"\u0641\u0648\u0644 \u0645\u062f\u0645\u0633 \u0644\u0627\u0645\u064a\u0646\u062c 397\u063a","sku":"000023071575","category_id":"3","unit_id":"4","supplier_id":"","sale_price":"0.2","purchase_price":"0.157","stock_quantity":"0","min_stock_level":"0","vat_rate":"5","promotion_start":"","promotion_end":"","promotion_percent":"0","edit_item":""} +2026-03-18 18:32:15 - POST: {"action":"translate","text":"\u0641\u0627\u0635\u0648\u0644\u064a\u0627 \u0644\u0627\u0645\u064a\u0646\u062c227\u062c\u0631\u0627\u0645","target":"en"} +2026-03-18 18:32:28 - POST: {"id":"58","name_en":"Leming Beans 227g","name_ar":"\u0641\u0627\u0635\u0648\u0644\u064a\u0627 \u0644\u0627\u0645\u064a\u0646\u062c227\u062c\u0631\u0627\u0645","sku":"000023071568","category_id":"3","unit_id":"4","supplier_id":"","sale_price":"0.15","purchase_price":"0.111","stock_quantity":"0","min_stock_level":"0","vat_rate":"5","promotion_start":"","promotion_end":"","promotion_percent":"0","edit_item":""}