From d44b57080a26ef77a8b114c946950b5412f9cb55 Mon Sep 17 00:00:00 2001 From: Antigravity Bot Date: Sun, 30 Aug 2026 21:56:25 +0330 Subject: [PATCH] feat: complete Bildirchin Quail Farm web app with wholesale & retail system --- data/database.sqlite | Bin 0 -> 81920 bytes public/assets/images/article1.svg | 6 + public/assets/images/article2.svg | 6 + public/assets/images/article3.svg | 6 + public/assets/images/quail_cage.svg | 30 ++ public/assets/images/quail_chick.svg | 19 + public/assets/images/quail_eggs_box.svg | 36 ++ public/assets/images/quail_feed_bag.svg | 19 + public/assets/images/quail_fertile_egg.svg | 17 + public/assets/images/quail_live.svg | 49 +++ public/assets/images/quail_meat.svg | 21 ++ public/assets/images/quail_packaging.svg | 8 + public/index.php | 103 ++++++ src/Config.php | 20 ++ src/Controllers/AdminController.php | 226 ++++++++++++ src/Controllers/ApiController.php | 38 ++ src/Controllers/BlogController.php | 29 ++ src/Controllers/CartController.php | 153 ++++++++ src/Controllers/HomeController.php | 34 ++ src/Controllers/OrderController.php | 119 +++++++ src/Controllers/ProductController.php | 36 ++ src/Controllers/WholesaleController.php | 50 +++ src/Database.php | 198 +++++++++++ src/Helpers.php | 61 ++++ src/Models/Admin.php | 34 ++ src/Models/Article.php | 53 +++ src/Models/Category.php | 41 +++ src/Models/Order.php | 144 ++++++++ src/Models/Product.php | 157 +++++++++ src/Models/Setting.php | 37 ++ src/Models/WholesaleInquiry.php | 43 +++ views/admin/dashboard.php | 129 +++++++ views/admin/invoice.php | 93 +++++ views/admin/layout_footer.php | 4 + views/admin/layout_header.php | 114 ++++++ views/admin/login.php | 51 +++ views/admin/order_detail.php | 96 +++++ views/admin/orders.php | 59 ++++ views/admin/products.php | 177 ++++++++++ views/admin/settings.php | 54 +++ views/admin/wholesale_inquiries.php | 66 ++++ views/layout/footer.php | 133 +++++++ views/layout/header.php | 52 +++ views/layout/navbar.php | 127 +++++++ views/pages/404.php | 18 + views/pages/about.php | 45 +++ views/pages/blog.php | 48 +++ views/pages/blog_detail.php | 50 +++ views/pages/cart.php | 140 ++++++++ views/pages/checkout.php | 165 +++++++++ views/pages/contact.php | 89 +++++ views/pages/home.php | 391 +++++++++++++++++++++ views/pages/order_success.php | 65 ++++ views/pages/product_detail.php | 128 +++++++ views/pages/products.php | 105 ++++++ views/pages/track_order.php | 110 ++++++ views/pages/wholesale.php | 138 ++++++++ 57 files changed, 4440 insertions(+) create mode 100644 data/database.sqlite create mode 100644 public/assets/images/article1.svg create mode 100644 public/assets/images/article2.svg create mode 100644 public/assets/images/article3.svg create mode 100644 public/assets/images/quail_cage.svg create mode 100644 public/assets/images/quail_chick.svg create mode 100644 public/assets/images/quail_eggs_box.svg create mode 100644 public/assets/images/quail_feed_bag.svg create mode 100644 public/assets/images/quail_fertile_egg.svg create mode 100644 public/assets/images/quail_live.svg create mode 100644 public/assets/images/quail_meat.svg create mode 100644 public/assets/images/quail_packaging.svg create mode 100644 public/index.php create mode 100644 src/Config.php create mode 100644 src/Controllers/AdminController.php create mode 100644 src/Controllers/ApiController.php create mode 100644 src/Controllers/BlogController.php create mode 100644 src/Controllers/CartController.php create mode 100644 src/Controllers/HomeController.php create mode 100644 src/Controllers/OrderController.php create mode 100644 src/Controllers/ProductController.php create mode 100644 src/Controllers/WholesaleController.php create mode 100644 src/Database.php create mode 100644 src/Helpers.php create mode 100644 src/Models/Admin.php create mode 100644 src/Models/Article.php create mode 100644 src/Models/Category.php create mode 100644 src/Models/Order.php create mode 100644 src/Models/Product.php create mode 100644 src/Models/Setting.php create mode 100644 src/Models/WholesaleInquiry.php create mode 100644 views/admin/dashboard.php create mode 100644 views/admin/invoice.php create mode 100644 views/admin/layout_footer.php create mode 100644 views/admin/layout_header.php create mode 100644 views/admin/login.php create mode 100644 views/admin/order_detail.php create mode 100644 views/admin/orders.php create mode 100644 views/admin/products.php create mode 100644 views/admin/settings.php create mode 100644 views/admin/wholesale_inquiries.php create mode 100644 views/layout/footer.php create mode 100644 views/layout/header.php create mode 100644 views/layout/navbar.php create mode 100644 views/pages/404.php create mode 100644 views/pages/about.php create mode 100644 views/pages/blog.php create mode 100644 views/pages/blog_detail.php create mode 100644 views/pages/cart.php create mode 100644 views/pages/checkout.php create mode 100644 views/pages/contact.php create mode 100644 views/pages/home.php create mode 100644 views/pages/order_success.php create mode 100644 views/pages/product_detail.php create mode 100644 views/pages/products.php create mode 100644 views/pages/track_order.php create mode 100644 views/pages/wholesale.php diff --git a/data/database.sqlite b/data/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..ded66387db93f949a319f2adb768295a29193ee6 GIT binary patch literal 81920 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 literal 0 HcmV?d00001 diff --git a/public/assets/images/article1.svg b/public/assets/images/article1.svg new file mode 100644 index 0000000..0eb5569 --- /dev/null +++ b/public/assets/images/article1.svg @@ -0,0 +1,6 @@ + + + + سالن مدرن پرورش بلدرچین + اصول تهویه، رطوبت، نور و قفس‌های مکانیزه + diff --git a/public/assets/images/article2.svg b/public/assets/images/article2.svg new file mode 100644 index 0000000..cc899e3 --- /dev/null +++ b/public/assets/images/article2.svg @@ -0,0 +1,6 @@ + + + + معجزه سلامت: خواص تخم بلدرچین + ویتامین B12، آهن، فسفر و انرژی فراوان + diff --git a/public/assets/images/article3.svg b/public/assets/images/article3.svg new file mode 100644 index 0000000..31d3bc2 --- /dev/null +++ b/public/assets/images/article3.svg @@ -0,0 +1,6 @@ + + + + فرمولاسیون جیره غذایی و دان + پروتئین خام، ضریب تبدیل و وزن‌گیری سریع + diff --git a/public/assets/images/quail_cage.svg b/public/assets/images/quail_cage.svg new file mode 100644 index 0000000..31f955e --- /dev/null +++ b/public/assets/images/quail_cage.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/images/quail_chick.svg b/public/assets/images/quail_chick.svg new file mode 100644 index 0000000..d52150c --- /dev/null +++ b/public/assets/images/quail_chick.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/images/quail_eggs_box.svg b/public/assets/images/quail_eggs_box.svg new file mode 100644 index 0000000..a479e63 --- /dev/null +++ b/public/assets/images/quail_eggs_box.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ۱۲ عددی + diff --git a/public/assets/images/quail_feed_bag.svg b/public/assets/images/quail_feed_bag.svg new file mode 100644 index 0000000..f281ca4 --- /dev/null +++ b/public/assets/images/quail_feed_bag.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + خوراک بلدرچین + پروتئین ۲۴٪ + ۲۵ KG + + + + + + diff --git a/public/assets/images/quail_fertile_egg.svg b/public/assets/images/quail_fertile_egg.svg new file mode 100644 index 0000000..51f440b --- /dev/null +++ b/public/assets/images/quail_fertile_egg.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + هچ بالای ۸۵٪ - نطفه‌دار تضمینی + diff --git a/public/assets/images/quail_live.svg b/public/assets/images/quail_live.svg new file mode 100644 index 0000000..e2c60ca --- /dev/null +++ b/public/assets/images/quail_live.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/images/quail_meat.svg b/public/assets/images/quail_meat.svg new file mode 100644 index 0000000..72d3fba --- /dev/null +++ b/public/assets/images/quail_meat.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + کشتار + روز + diff --git a/public/assets/images/quail_packaging.svg b/public/assets/images/quail_packaging.svg new file mode 100644 index 0000000..eaf7da8 --- /dev/null +++ b/public/assets/images/quail_packaging.svg @@ -0,0 +1,8 @@ + + + + + + + بسته‌بندی صادراتی + diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..d713d0e --- /dev/null +++ b/public/index.php @@ -0,0 +1,103 @@ +index(); +} elseif ($requestUri === '/about') { + (new Controllers\HomeController())->about(); +} elseif ($requestUri === '/contact') { + (new Controllers\HomeController())->contact(); +} elseif ($requestUri === '/products') { + (new Controllers\ProductController())->index(); +} elseif (preg_match('#^/product/([a-zA-Z0-9_-]+)$#', $requestUri, $matches)) { + (new Controllers\ProductController())->detail($matches[1]); +} elseif ($requestUri === '/cart') { + (new Controllers\CartController())->index(); +} elseif ($requestUri === '/cart/add' && $requestMethod === 'POST') { + (new Controllers\CartController())->add(); +} elseif ($requestUri === '/cart/update' && $requestMethod === 'POST') { + (new Controllers\CartController())->update(); +} elseif ($requestUri === '/cart/remove') { + (new Controllers\CartController())->remove(); +} elseif ($requestUri === '/checkout') { + (new Controllers\OrderController())->checkout(); +} elseif ($requestUri === '/order/submit' && $requestMethod === 'POST') { + (new Controllers\OrderController())->submit(); +} elseif ($requestUri === '/order/success') { + (new Controllers\OrderController())->success(); +} elseif ($requestUri === '/track') { + (new Controllers\OrderController())->track(); +} elseif ($requestUri === '/wholesale') { + (new Controllers\WholesaleController())->index(); +} elseif ($requestUri === '/wholesale/inquiry' && $requestMethod === 'POST') { + (new Controllers\WholesaleController())->submitInquiry(); +} elseif ($requestUri === '/blog') { + (new Controllers\BlogController())->index(); +} elseif (preg_match('#^/blog/([a-zA-Z0-9_-]+)$#', $requestUri, $matches)) { + (new Controllers\BlogController())->detail($matches[1]); +} elseif ($requestUri === '/api/wholesale/calculate') { + (new Controllers\ApiController())->calculateWholesale(); +} +// Admin Routes +elseif ($requestUri === '/admin' || $requestUri === '/admin/dashboard') { + (new Controllers\AdminController())->dashboard(); +} elseif ($requestUri === '/admin/login') { + (new Controllers\AdminController())->login(); +} elseif ($requestUri === '/admin/logout') { + (new Controllers\AdminController())->logout(); +} elseif ($requestUri === '/admin/products') { + (new Controllers\AdminController())->products(); +} elseif ($requestUri === '/admin/product/save' && $requestMethod === 'POST') { + (new Controllers\AdminController())->productSave(); +} elseif ($requestUri === '/admin/product/delete' && $requestMethod === 'POST') { + (new Controllers\AdminController())->productDelete(); +} elseif ($requestUri === '/admin/orders') { + (new Controllers\AdminController())->orders(); +} elseif (preg_match('#^/admin/order/([0-9]+)$#', $requestUri, $matches)) { + (new Controllers\AdminController())->orderDetail((int)$matches[1]); +} elseif ($requestUri === '/admin/order/update-status' && $requestMethod === 'POST') { + (new Controllers\AdminController())->orderUpdateStatus(); +} elseif (preg_match('#^/admin/invoice/([0-9]+)$#', $requestUri, $matches)) { + (new Controllers\AdminController())->invoice((int)$matches[1]); +} elseif ($requestUri === '/admin/wholesale-inquiries') { + (new Controllers\AdminController())->wholesaleInquiries(); +} elseif ($requestUri === '/admin/wholesale-inquiry/update-status' && $requestMethod === 'POST') { + (new Controllers\AdminController())->inquiryUpdateStatus(); +} elseif ($requestUri === '/admin/settings') { + (new Controllers\AdminController())->settings(); +} else { + http_response_code(404); + require __DIR__ . '/../views/pages/404.php'; +} diff --git a/src/Config.php b/src/Config.php new file mode 100644 index 0000000..d283939 --- /dev/null +++ b/src/Config.php @@ -0,0 +1,20 @@ +checkAuth(); + $stats = Order::getStats(); + $recentOrders = Order::all(8); + $recentInquiries = WholesaleInquiry::all(5); + + require __DIR__ . '/../../views/admin/dashboard.php'; + } + + public function products(): void + { + $this->checkAuth(); + $categories = Category::all(); + $products = Product::all(100); + + require __DIR__ . '/../../views/admin/products.php'; + } + + public function productSave(): void + { + $this->checkAuth(); + $id = (int)($_POST['id'] ?? 0); + $name = Helpers::sanitize($_POST['name'] ?? ''); + $categoryId = (int)($_POST['category_id'] ?? 1); + $slug = Helpers::sanitize($_POST['slug'] ?? ''); + if (!$slug) { + $slug = 'product-' . time(); + } + + $data = [ + 'category_id' => $categoryId, + 'name' => $name, + 'slug' => $slug, + 'short_desc' => Helpers::sanitize($_POST['short_desc'] ?? ''), + 'full_desc' => Helpers::sanitize($_POST['full_desc'] ?? ''), + 'price' => (float)($_POST['price'] ?? 0), + 'unit' => Helpers::sanitize($_POST['unit'] ?? 'عدد'), + 'stock' => (int)($_POST['stock'] ?? 0), + 'image' => Helpers::sanitize($_POST['image'] ?? '/assets/images/quail_live.svg'), + 'is_wholesale_available' => isset($_POST['is_wholesale_available']) ? 1 : 0, + 'wholesale_min_qty' => (int)($_POST['wholesale_min_qty'] ?? 50), + 'wholesale_price' => (float)($_POST['wholesale_price'] ?? 0), + 'wholesale_tier2_qty' => (int)($_POST['wholesale_tier2_qty'] ?? 200), + 'wholesale_tier2_price' => (float)($_POST['wholesale_tier2_price'] ?? 0), + 'is_featured' => isset($_POST['is_featured']) ? 1 : 0 + ]; + + if ($id > 0) { + Product::update($id, $data); + Helpers::flash('success', 'محصول با موفقیت به‌روزرسانی شد.'); + } else { + Product::create($data); + Helpers::flash('success', 'محصول جدید با موفقیت اضافه شد.'); + } + + header('Location: /admin/products'); + exit; + } + + public function productDelete(): void + { + $this->checkAuth(); + $id = (int)($_POST['id'] ?? 0); + if ($id > 0) { + Product::delete($id); + Helpers::flash('success', 'محصول با موفقیت حذف شد.'); + } + header('Location: /admin/products'); + exit; + } + + public function orders(): void + { + $this->checkAuth(); + $status = $_GET['status'] ?? null; + $orders = Order::all(100, $status); + + require __DIR__ . '/../../views/admin/orders.php'; + } + + public function orderDetail(int $id): void + { + $this->checkAuth(); + $order = Order::findById($id); + if (!$order) { + header('Location: /admin/orders'); + exit; + } + + require __DIR__ . '/../../views/admin/order_detail.php'; + } + + public function orderUpdateStatus(): void + { + $this->checkAuth(); + $id = (int)($_POST['order_id'] ?? 0); + $status = Helpers::sanitize($_POST['status'] ?? 'pending'); + + if ($id > 0) { + Order::updateStatus($id, $status); + Helpers::flash('success', 'وضعیت سفارش به‌روزرسانی شد.'); + } + + header('Location: /admin/order/' . $id); + exit; + } + + public function invoice(int $id): void + { + $this->checkAuth(); + $order = Order::findById($id); + if (!$order) { + die('سفارش یافت نشد'); + } + + $settings = Setting::getAll(); + require __DIR__ . '/../../views/admin/invoice.php'; + } + + public function wholesaleInquiries(): void + { + $this->checkAuth(); + $inquiries = WholesaleInquiry::all(100); + + require __DIR__ . '/../../views/admin/wholesale_inquiries.php'; + } + + public function inquiryUpdateStatus(): void + { + $this->checkAuth(); + $id = (int)($_POST['id'] ?? 0); + $status = Helpers::sanitize($_POST['status'] ?? 'reviewed'); + + if ($id > 0) { + WholesaleInquiry::updateStatus($id, $status); + Helpers::flash('success', 'وضعیت درخواست همکاری به‌روز شد.'); + } + + header('Location: /admin/wholesale-inquiries'); + exit; + } + + public function settings(): void + { + $this->checkAuth(); + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + foreach ($_POST as $k => $v) { + if ($k !== 'csrf') { + Setting::set($k, trim((string)$v)); + } + } + Helpers::flash('success', 'تنظیمات فروشگاه با موفقیت ذخیره شد.'); + header('Location: /admin/settings'); + exit; + } + + $settings = Setting::getAll(); + require __DIR__ . '/../../views/admin/settings.php'; + } +} diff --git a/src/Controllers/ApiController.php b/src/Controllers/ApiController.php new file mode 100644 index 0000000..bf5400a --- /dev/null +++ b/src/Controllers/ApiController.php @@ -0,0 +1,38 @@ + false, 'message' => 'محصول یافت نشد'], 404); + } + + $calc = Product::calculateUnitPrice($product, $quantity); + + Helpers::jsonResponse([ + 'success' => true, + 'product_name' => $product['name'], + 'quantity' => $quantity, + 'unit' => $product['unit'], + 'unit_price' => $calc['unit_price'], + 'unit_price_formatted' => Helpers::formatPrice($calc['unit_price']), + 'regular_price_formatted' => Helpers::formatPrice($product['price']), + 'total_price' => $calc['total_price'], + 'total_price_formatted' => Helpers::formatPrice($calc['total_price']), + 'is_wholesale' => $calc['is_wholesale'], + 'total_saved' => $calc['total_saved'], + 'total_saved_formatted' => Helpers::formatPrice($calc['total_saved']) + ]); + } +} diff --git a/src/Controllers/BlogController.php b/src/Controllers/BlogController.php new file mode 100644 index 0000000..b236bc6 --- /dev/null +++ b/src/Controllers/BlogController.php @@ -0,0 +1,29 @@ + $quantity) { + $product = Product::findById((int)$productId); + if (!$product) { + continue; + } + + $calc = Product::calculateUnitPrice($product, (int)$quantity); + $itemRetailTotal = (float)$product['price'] * (int)$quantity; + + $items[] = [ + 'product' => $product, + 'quantity' => (int)$quantity, + 'unit_price' => $calc['unit_price'], + 'regular_price' => (float)$product['price'], + 'total_price' => $calc['total_price'], + 'is_wholesale' => $calc['is_wholesale'], + 'savings' => $calc['total_saved'] + ]; + + $totalRetail += $itemRetailTotal; + $totalFinal += $calc['total_price']; + $totalItemsCount += (int)$quantity; + $totalSavings += $calc['total_saved']; + } + + return [ + 'items' => $items, + 'total_retail' => $totalRetail, + 'total_final' => $totalFinal, + 'total_savings' => $totalSavings, + 'total_count' => $totalItemsCount + ]; + } + + public function index(): void + { + $cartData = self::getCartDetails(); + require __DIR__ . '/../../views/pages/cart.php'; + } + + public function add(): void + { + $productId = (int)($_POST['product_id'] ?? 0); + $quantity = max(1, (int)($_POST['quantity'] ?? 1)); + + $product = Product::findById($productId); + if (!$product) { + Helpers::jsonResponse(['success' => false, 'message' => 'محصول یافت نشد'], 404); + } + + $cart = self::getCart(); + if (isset($cart[$productId])) { + $cart[$productId] += $quantity; + } else { + $cart[$productId] = $quantity; + } + + self::saveCart($cart); + + if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) || (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) { + $details = self::getCartDetails(); + Helpers::jsonResponse([ + 'success' => true, + 'message' => 'محصول با موفقیت به سبد خرید اضافه شد', + 'cart_count' => count($details['items']), + 'total_final_formatted' => Helpers::formatPrice($details['total_final']) + ]); + } + + Helpers::flash('success', 'محصول به سبد خرید اضافه شد'); + header('Location: /cart'); + exit; + } + + public function update(): void + { + $productId = (int)($_POST['product_id'] ?? 0); + $quantity = (int)($_POST['quantity'] ?? 1); + + $cart = self::getCart(); + if ($quantity <= 0) { + unset($cart[$productId]); + } else { + $cart[$productId] = $quantity; + } + + self::saveCart($cart); + $details = self::getCartDetails(); + + Helpers::jsonResponse([ + 'success' => true, + 'cart' => $details, + 'cart_count' => count($details['items']), + 'total_final_formatted' => Helpers::formatPrice($details['total_final']), + 'total_savings_formatted' => Helpers::formatPrice($details['total_savings']) + ]); + } + + public function remove(): void + { + $productId = (int)($_POST['product_id'] ?? 0); + $cart = self::getCart(); + unset($cart[$productId]); + self::saveCart($cart); + + Helpers::flash('success', 'محصول از سبد خرید حذف شد'); + header('Location: /cart'); + exit; + } + + public static function clear(): void + { + if (session_status() === PHP_SESSION_NONE) { + session_start(); + } + unset($_SESSION['cart']); + } +} diff --git a/src/Controllers/HomeController.php b/src/Controllers/HomeController.php new file mode 100644 index 0000000..93b85ec --- /dev/null +++ b/src/Controllers/HomeController.php @@ -0,0 +1,34 @@ + $orderCode, + 'customer_name' => $name, + 'customer_phone' => $phone, + 'customer_email' => Helpers::sanitize($_POST['customer_email'] ?? ''), + 'province' => $province, + 'city' => $city, + 'address' => $address, + 'postal_code' => $postalCode, + 'notes' => $notes, + 'shipping_method' => $shippingMethod, + 'payment_method' => $paymentMethod, + 'total_amount' => $cartData['total_retail'], + 'discount_amount' => $cartData['total_savings'], + 'final_amount' => $cartData['total_final'] + ]; + + $orderItems = []; + foreach ($cartData['items'] as $item) { + $orderItems[] = [ + 'product_id' => $item['product']['id'], + 'product_name' => $item['product']['name'], + 'quantity' => $item['quantity'], + 'unit_price' => $item['unit_price'], + 'total_price' => $item['total_price'], + 'is_wholesale' => $item['is_wholesale'] + ]; + } + + try { + $orderId = Order::create($orderData, $orderItems); + CartController::clear(); + + header('Location: /order/success?code=' . urlencode($orderCode)); + exit; + } catch (\Throwable $e) { + Helpers::flash('error', 'خطایی در ثبت سفارش رخ داد: ' . $e->getMessage()); + header('Location: /checkout'); + exit; + } + } + + public function success(): void + { + $code = $_GET['code'] ?? ''; + $order = Order::findByCode($code); + if (!$order) { + header('Location: /'); + exit; + } + + $settings = Setting::getAll(); + require __DIR__ . '/../../views/pages/order_success.php'; + } + + public function track(): void + { + $order = null; + $searched = false; + + if ($_SERVER['REQUEST_METHOD'] === 'POST' || isset($_GET['code'])) { + $code = trim($_POST['order_code'] ?? ($_GET['code'] ?? '')); + if ($code) { + $searched = true; + $order = Order::findByCode($code); + } + } + + require __DIR__ . '/../../views/pages/track_order.php'; + } +} diff --git a/src/Controllers/ProductController.php b/src/Controllers/ProductController.php new file mode 100644 index 0000000..72bbc2f --- /dev/null +++ b/src/Controllers/ProductController.php @@ -0,0 +1,36 @@ + (int)$p['is_wholesale_available'] === 1); + $settings = Setting::getAll(); + require __DIR__ . '/../../views/pages/wholesale.php'; + } + + public function submitInquiry(): void + { + $name = Helpers::sanitize($_POST['customer_name'] ?? ''); + $phone = Helpers::sanitize($_POST['phone'] ?? ''); + $company = Helpers::sanitize($_POST['company_name'] ?? ''); + $product = Helpers::sanitize($_POST['product_requested'] ?? ''); + $qty = Helpers::sanitize($_POST['estimated_qty'] ?? ''); + $city = Helpers::sanitize($_POST['city'] ?? ''); + $notes = Helpers::sanitize($_POST['notes'] ?? ''); + + if (!$name || !$phone || !$product) { + Helpers::flash('error', 'لطفاً نام، شماره تماس و محصول مورد نظر را وارد نمایید.'); + header('Location: /wholesale'); + exit; + } + + WholesaleInquiry::create([ + 'customer_name' => $name, + 'phone' => $phone, + 'company_name' => $company, + 'product_requested' => $product, + 'estimated_qty' => $qty, + 'city' => $city, + 'notes' => $notes + ]); + + Helpers::flash('success', 'درخواست همکاری و استعلام قیمت عمده شما با موفقیت ثبت شد. کارشناسان مزرعه در اسرع وقت با شما تماس خواهند گرفت.'); + header('Location: /wholesale#success'); + exit; + } +} diff --git a/src/Database.php b/src/Database.php new file mode 100644 index 0000000..053e8cd --- /dev/null +++ b/src/Database.php @@ -0,0 +1,198 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + self::initSchema(self::$instance); + } catch (PDOException $e) { + die("خطا در اتصال به پایگاه داده: " . $e->getMessage()); + } + } + + return self::$instance; + } + + private static function initSchema(PDO $db): void + { + $db->exec(" + CREATE TABLE IF NOT EXISTS categories ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + slug TEXT NOT NULL UNIQUE, + icon TEXT, + description TEXT, + sort_order INTEGER DEFAULT 0 + ); + + CREATE TABLE IF NOT EXISTS products ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + category_id INTEGER NOT NULL, + name TEXT NOT NULL, + slug TEXT NOT NULL UNIQUE, + short_desc TEXT, + full_desc TEXT, + price REAL NOT NULL, + unit TEXT NOT NULL DEFAULT 'عدد', + stock INTEGER DEFAULT 100, + image TEXT, + is_wholesale_available INTEGER DEFAULT 1, + wholesale_min_qty INTEGER DEFAULT 50, + wholesale_price REAL DEFAULT 0, + wholesale_tier2_qty INTEGER DEFAULT 200, + wholesale_tier2_price REAL DEFAULT 0, + is_featured INTEGER DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (category_id) REFERENCES categories(id) + ); + + CREATE TABLE IF NOT EXISTS orders ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + order_code TEXT NOT NULL UNIQUE, + customer_name TEXT NOT NULL, + customer_phone TEXT NOT NULL, + customer_email TEXT, + province TEXT, + city TEXT, + address TEXT, + postal_code TEXT, + notes TEXT, + shipping_method TEXT, + payment_method TEXT, + total_amount REAL NOT NULL, + discount_amount REAL DEFAULT 0, + final_amount REAL NOT NULL, + status TEXT DEFAULT 'pending', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + + CREATE TABLE IF NOT EXISTS order_items ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + order_id INTEGER NOT NULL, + product_id INTEGER NOT NULL, + product_name TEXT NOT NULL, + quantity INTEGER NOT NULL, + unit_price REAL NOT NULL, + total_price REAL NOT NULL, + is_wholesale INTEGER DEFAULT 0, + FOREIGN KEY (order_id) REFERENCES orders(id) + ); + + CREATE TABLE IF NOT EXISTS wholesale_inquiries ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + customer_name TEXT NOT NULL, + phone TEXT NOT NULL, + company_name TEXT, + product_requested TEXT NOT NULL, + estimated_qty TEXT, + city TEXT, + notes TEXT, + status TEXT DEFAULT 'new', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + + CREATE TABLE IF NOT EXISTS articles ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + slug TEXT NOT NULL UNIQUE, + summary TEXT, + content TEXT, + image TEXT, + author TEXT DEFAULT 'مدیریت مزرعه', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + + CREATE TABLE IF NOT EXISTS settings ( + key TEXT PRIMARY KEY, + value TEXT + ); + + CREATE TABLE IF NOT EXISTS admins ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL UNIQUE, + password_hash TEXT NOT NULL, + display_name TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + "); + + self::seedInitialData($db); + } + + private static function seedInitialData(PDO $db): void + { + $stmt = $db->query("SELECT COUNT(*) as count FROM categories"); + if ((int)$stmt->fetch()['count'] === 0) { + // Seed Categories + $db->exec(" + INSERT INTO categories (name, slug, icon, description, sort_order) VALUES + ('بلدرچین گوشتی و زنده', 'quail-birds', 'fas fa-feather-alt', 'انواع بلدرچین زنده، کشتار روز، منجمد و جوجه پرورشی', 1), + ('تخم بلدرچین (خوراکی و نطفه‌دار)', 'quail-eggs', 'fas fa-egg', 'تخم خوراکی تازه بسته‌بندی و تخم نطفه‌دار جوجه‌کشی با هچ بالا', 2), + ('دان و خوراک تخصصی', 'quail-feed', 'fas fa-seedling', 'دان پلت و آردی استارتر، رشد و تخم‌گذار با آنالیز دقیق پروتئین', 3), + ('تجهیزات و ملزومات پرورش', 'equipment', 'fas fa-warehouse', 'قفس‌های استاندارد، آبخوری، دانخوری و شانه و کارتن بسته‌بندی', 4); + "); + + // Seed Products + $db->exec(" + INSERT INTO products (category_id, name, slug, short_desc, full_desc, price, unit, stock, image, is_wholesale_available, wholesale_min_qty, wholesale_price, wholesale_tier2_qty, wholesale_tier2_price, is_featured) VALUES + (1, 'بلدرچین گوشتی کشتار روز (بسته ۴ عددی)', 'quail-meat-4pack', 'گوشت تازه بلدرچین کشتار روز، پاک‌شده و وکیوم بهداشتی تحت نظارت دامپزشکی', 'گوشت بلدرچین تازه کشتار روز مزرعه زرین، پاک‌شده کامل بدون امعاء و احشاء و بدون کله و پا، شسته‌شده با آب سرد بهداشتی و بسته‌بندی وکیوم شده در ظروف کریستالی مقاوم تحت نظارت مستقیم کارشناسان سازمان دامپزشکی کل کشور. گوشت بلدرچین منبعی بی‌نظیر از فسفر، آهن و پروتئین بدون چربی مضر است.', 185000, 'بسته', 250, '/assets/images/quail_meat.svg', 1, 20, 165000, 100, 150000, 1), + (1, 'بلدرچین زنده بالغ پرواری (سنگین وزن)', 'live-quail-adult', 'بلدرچین زنده نژاد سنگین سنگین ژاپنی، وزن میانگین ۲۲۰ الی ۲۶۰ گرم، کاملا سالم و واکسینه‌شده', 'بلدرچین‌های زنده گله مولد و پرواری نژاد ژاپنی اصلاح شده سنگین وزن (وزن زنده بین ۲۲۰ الی ۲۶۰ گرم). تغذیه شده با بهترین جیره سوپراستارتر و دان ارگانیک فاقد آنتی‌بیوتیک، مناسب جهت کشتارگاه‌ها، رستوران‌های سنتی و سالن‌های پرورشی سراسر کشور.', 58000, 'قطعه', 1500, '/assets/images/quail_live.svg', 1, 100, 49000, 500, 44000, 1), + (1, 'جوجه بلدرچین یک‌روزه اصلاح‌نژاد شده', 'quail-chick-1day', 'جوجه بلدرچین یک‌روزه نژاد سنگین تخم‌گذار و گوشتی با راندمان رشد فوق‌العاده', 'تولید هفتگی بیش از ۲۰ هزار قطعه جوجه بلدرچین یک‌روزه هچ شده در انکوباتورهای تمام‌اتوماتیک مزرعه. تفکیک شده، ضدعفونی شده و بسیار سرزنده با تضمین کمترین میزان تلفات حین حمل در کارتن‌های تهویه‌دار مخصوص.', 12000, 'قطعه', 3000, '/assets/images/quail_chick.svg', 1, 500, 9500, 2000, 8000, 0), + (2, 'تخم بلدرچین خوراکی تازه (بسته ۱۲ عددی)', 'quail-edible-eggs-12', 'تخم بلدرچین ارگانیک و تازه با زرده طلایی، سرشار از فسفر، آهن و ویتامین B12', 'تخم بلدرچین تازه تولید روز، جمع‌آوری شده با رعایت کامل اصول بهداشت و قرنطینه. مناسب برای تقویت سیستم ایمنی کودکان، ورزشکاران و سالمندان. بسته‌بندی کریستالی استاندارد و شفاف ۱۲ عددی.', 38000, 'بسته', 400, '/assets/images/quail_eggs_box.svg', 1, 50, 32000, 200, 28000, 1), + (2, 'تخم نطفه‌دار بلدرچین نژاد ژاپنی (هچ بالای ۸۵٪)', 'quail-fertile-eggs', 'تخم نطفه‌دار تازه روز، جمع‌آوری شده از گله مولد جوان و اصلاح‌شده، مناسب دستگاه جوجه‌کشی', 'تخم‌های نطفه‌دار با نسبت خروس به مرغ ۱ به ۳، جمع‌آوری روزانه و نگهداری در دمای استاندارد ۱۶ درجه سانتی‌گراد و رطوبت ۶۵ درصد. تضمین نطفه‌داری بالای ۹۰ درصد و راندمان هچ بیش از ۸۵ درصد در دستگاه‌های جوجه‌کشی استاندارد.', 4500, 'عدد', 5000, '/assets/images/quail_fertile_egg.svg', 1, 200, 3800, 1000, 3200, 1), + (3, 'دان استارتر سوپر بلدرچین (کیسه ۲۵ کیلویی)', 'quail-starter-feed-25kg', 'خوراک مخصوص هفته اول تا سوم، پروتئین ۲۴٪، غنی از ویتامین‌ها و اسیدهای آمینه ضروری', 'جیره فرموله شده توسط متخصصان تغذیه طیور با استفاده از کنجاله سویای باکیفیت و ذرت برزیلی درجه یک. حاوی ۲۴.۵ درصد پروتئین خام، متیونین، لیزین، کلسیم، فسفر و پرمیکس ویتامینه کامل برای حداکثر سرعت رشد جوجه‌ها.', 680000, 'کیسه', 80, '/assets/images/quail_feed_bag.svg', 1, 10, 620000, 50, 580000, 1), + (3, 'دان پلت رشد و پرواری بلدرچین (کیسه ۲۵ کیلویی)', 'quail-grower-feed-25kg', 'خوراک پلت دوره رشد و پروار بلدرچین، ضریب تبدیل عالی، وزن‌گیری سریع', 'خوراک پلت ریز ۲ میلی‌متری مخصوص سن ۲۱ روزگی تا زمان کشتار (حدود ۴۰ روزگی). پروتئین ۲۰.۵ درصد، انرژی بالا جهت رشد سریع عضلات سینه و ران با ضریب تبدیل غذایی ایده‌آل ۲.۱.', 640000, 'کیسه', 120, '/assets/images/quail_feed_bag.svg', 1, 10, 590000, 50, 550000, 0), + (3, 'دان پلت بلدرچین تخم‌گذار (کیسه ۲۵ کیلویی)', 'quail-layer-feed-25kg', 'جیره تخصصی بلدرچین تخم‌گذار حاوی کلسیم و فسفر بالانس شده جهت استحکام پوسته و ماندگاری تولید', 'جیره تقویتی ویژه گله‌های تخم‌گذار و مولد بلدرچین. حاوی ۳.۲ درصد کلسیم و پروتئین ۱۹ درصد جهت تضمین راندمان تخم‌گذاری مداوم بالای ۸۰ درصد و استحکام پوسته تخم بدون لمبه شدن.', 660000, 'کیسه', 100, '/assets/images/quail_feed_bag.svg', 1, 10, 610000, 50, 570000, 1), + (4, 'قفس ۴ طبقه مکانیزه بلدرچین (گالوانیزه گرم)', 'quail-cage-4layer', 'قفس صنعتی با گنجایش ۱۳۰ الی ۱۵۰ قطعه، مجهز به آبخوری نیپل اتوماتیک، سینی فضولات و دانخوری ضد هدررفت', 'قفس مهندسی‌ساز صنعتی ساخته شده از توری گالوانیزه گرم ضدزنگ و قابل شستشو با اسید و مواد شوینده قوی. مجهز به ۴ ردیف آبخوری نیپل با کاسه استیل، سیستم شیب تخم‌گذار جهت هدایت خودکار تخم‌ها به بیرون، و سینی گالوانیزه تخلیه سریع کود.', 4200000, 'دستگاه', 20, '/assets/images/quail_cage.svg', 1, 5, 3850000, 20, 3500000, 1), + (4, 'شانه و کارتن صادراتی بسته‌بندی تخم بلدرچین', 'quail-egg-packaging-carton', 'شانه پلاستیکی کریستالی ۱۲ عددی به همراه کارتن مادر مستحکم مناسب حمل و نقل فروشگاهی', 'شانه‌های شفاف فودگرید با قفل فشاری محکم به همراه کارتن‌های ۵ لایه صادراتی، مقاوم در برابر رطوبت و ضربات حین حمل بین‌شهری و باربری.', 4500, 'عدد', 2000, '/assets/images/quail_packaging.svg', 1, 500, 3600, 2000, 3100, 0); + "); + + // Seed Articles + $db->exec(" + INSERT INTO articles (title, slug, summary, content, image) VALUES + ('راهنمای گام به گام راه‌اندازی سالن پرورش بلدرچین', 'quail-farming-complete-guide', 'بررسی شرایط دما، رطوبت، نوردهی و اصول بهداشتی برای شروع پرورش بلدرچین گوشتی و تخم‌گذار در مقیاس خرد و صنعتی.', 'پرورش بلدرچین به دلیل دوره رشد کوتاه (حدود ۴۰ روز برای کشتار) و بلوغ زودرس جنسی (شروع تخم‌گذاری از سن ۴۵ الی ۵۰ روزگی) یکی از سودآورترین و مطمئن‌ترین شاخه‌های پرورش طیور است.\n\n### ۱. مشخصات سالن و تجهیزات:\n- دمای سالن برای جوجه‌ها در هفته اول باید حدود ۳۵ درجه سانتی‌گراد باشد و به تدریج کاهش یابد.\n- رطوبت نسبی بین ۶۰ تا ۶۵ درصد تنظیم شود.\n- سیستم تهویه باید هوای تازه را بدون ایجاد کوران مستقیم به سالن برساند.\n\n### ۲. مزایای استفاده از قفس استاندارد:\nاستفاده از قفس‌های مکانیزه به کاهش شدید بیماری‌ها، افزایش راندمان تخم‌گذاری و صرفه‌جویی در فضای سالن کمک شایانی می‌کند.', '/assets/images/article1.svg'), + ('معجزه تخم بلدرچین: بمب ویتامین و خواص دارویی', 'quail-egg-benefits-and-nutrition', 'چرا پزشکان تخم بلدرچین را به عنوان یکی از کامل‌ترین منابع پروتئین و مواد معدنی برای کودکان و سالمندان توصیه می‌کنند؟', 'تخم بلدرچین با وجود جثه کوچکش، ارزش غذایی خارق‌العاده‌ای دارد. هر تخم بلدرچین حدود ۵ برابر تخم مرغ فسفر، ۶ برابر ویتامین B12 و ۷ برابر آهن دارد.\n\n### مهم‌ترین خواص تخم بلدرچین:\n۱. تقویت سیستم ایمنی بدن در برابر ویروس‌ها\n۲. رشد ذهنی و جسمی کودکان و نوجوانان\n۳. فاقد کلسترول بد (LDL) و بسیار مفید برای قلب\n۴. بهبود حافظه و پیشگیری از کم‌خونی و خستگی مفرط\n\nمصرف روزانه ۲ الی ۳ عدد تخم بلدرچین انرژی لازم برای یک روز کاری پرنشاط را تامین می‌کند.', '/assets/images/article2.svg'), + ('فرمولاسیون و اهمیت کیفیت دان در وزن‌گیری بلدرچین', 'quail-feed-formulation-and-protein', 'نقش میزان پروتئین خام، کلسیم و متیونین در کاهش دوره پروار و افزایش کیفیت گوشت بلدرچین.', 'بلدرچین‌ها نیاز به پروتئین بسیار بالاتری نسبت به مرغ دارند. دان استارتر باید حداقل حاوی ۲۴ الی ۲۵ درصد پروتئین خام باشد تا عضلات سینه به سرعت رشد کنند.\n\n### ویژگی‌های دان باکیفیت مزرعه زرین:\n- استفاده از کنجاله سویای باکیفیت و ذرت درجه یک\n- بالانس دقیق اسیدهای آمینه لیزین و متیونین\n- پلت‌سازی با دمای کنترل‌شده جهت حفظ ویتامین‌ها\n- بدون استفاده از هرگونه آنتی‌بیوتیک غیرمجاز یا هورمون', '/assets/images/article3.svg'); + "); + + // Seed Admin User + $adminPass = password_hash(Config::ADMIN_PASS, PASSWORD_DEFAULT); + $db->exec(" + INSERT INTO admins (username, password_hash, display_name) VALUES + ('admin', '$adminPass', 'مدیر مزرعه بلدرچین زرین'); + "); + + // Seed Settings + $db->exec(" + INSERT INTO settings (key, value) VALUES + ('farm_name', 'مزرعه و مجتمع پرورشی بلدرچین زرین'), + ('phone', '09121234567'), + ('landline', '02188889999'), + ('address', 'تهران، جاده مخصوص، کیلومتر ۲۲، مزرعه صنعتی بلدرچین زرین'), + ('shipping_freight_rate', '120000'), + ('free_shipping_threshold', '2000000'), + ('card_number', '6037-9918-1234-5678'), + ('card_holder', 'مزرعه پرورشی بلدرچین زرین - علیزاده'); + "); + } + } +} diff --git a/src/Helpers.php b/src/Helpers.php new file mode 100644 index 0000000..8c3f430 --- /dev/null +++ b/src/Helpers.php @@ -0,0 +1,61 @@ +prepare("SELECT * FROM admins WHERE username = :username"); + $stmt->execute([':username' => $username]); + $admin = $stmt->fetch(); + + if ($admin && password_verify($password, $admin['password_hash'])) { + return $admin; + } + + return null; + } + + public static function updatePassword(int $id, string $newPassword): bool + { + $db = Database::getConnection(); + $stmt = $db->prepare("UPDATE admins SET password_hash = :hash WHERE id = :id"); + return $stmt->execute([ + ':id' => $id, + ':hash' => password_hash($newPassword, PASSWORD_DEFAULT) + ]); + } +} diff --git a/src/Models/Article.php b/src/Models/Article.php new file mode 100644 index 0000000..cc7ba96 --- /dev/null +++ b/src/Models/Article.php @@ -0,0 +1,53 @@ +query("SELECT * FROM articles ORDER BY id DESC LIMIT " . (int)$limit); + return $stmt->fetchAll(); + } + + public static function findById(int $id): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT * FROM articles WHERE id = :id"); + $stmt->execute([':id' => $id]); + $row = $stmt->fetch(); + return $row ?: null; + } + + public static function findBySlug(string $slug): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT * FROM articles WHERE slug = :slug"); + $stmt->execute([':slug' => $slug]); + $row = $stmt->fetch(); + return $row ?: null; + } + + public static function create(array $data): int + { + $db = Database::getConnection(); + $stmt = $db->prepare(" + INSERT INTO articles (title, slug, summary, content, image, author) + VALUES (:title, :slug, :summary, :content, :image, :author) + "); + $stmt->execute([ + ':title' => $data['title'], + ':slug' => $data['slug'], + ':summary' => $data['summary'] ?? '', + ':content' => $data['content'] ?? '', + ':image' => $data['image'] ?? '/assets/images/article1.svg', + ':author' => $data['author'] ?? 'مدیریت مزرعه' + ]); + return (int)$db->lastInsertId(); + } +} diff --git a/src/Models/Category.php b/src/Models/Category.php new file mode 100644 index 0000000..2a21e71 --- /dev/null +++ b/src/Models/Category.php @@ -0,0 +1,41 @@ +query(" + SELECT c.*, COUNT(p.id) as products_count + FROM categories c + LEFT JOIN products p ON c.id = p.category_id + GROUP BY c.id + ORDER BY c.sort_order ASC, c.id ASC + "); + return $stmt->fetchAll(); + } + + public static function findById(int $id): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT * FROM categories WHERE id = :id"); + $stmt->execute([':id' => $id]); + $row = $stmt->fetch(); + return $row ?: null; + } + + public static function findBySlug(string $slug): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT * FROM categories WHERE slug = :slug"); + $stmt->execute([':slug' => $slug]); + $row = $stmt->fetch(); + return $row ?: null; + } +} diff --git a/src/Models/Order.php b/src/Models/Order.php new file mode 100644 index 0000000..1e743ce --- /dev/null +++ b/src/Models/Order.php @@ -0,0 +1,144 @@ +prepare($query); + $stmt->execute($params); + return $stmt->fetchAll(); + } + + public static function findById(int $id): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT * FROM orders WHERE id = :id"); + $stmt->execute([':id' => $id]); + $order = $stmt->fetch(); + if (!$order) { + return null; + } + + $itemsStmt = $db->prepare("SELECT * FROM order_items WHERE order_id = :order_id"); + $itemsStmt->execute([':order_id' => $id]); + $order['items'] = $itemsStmt->fetchAll(); + + return $order; + } + + public static function findByCode(string $code): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT * FROM orders WHERE order_code = :code"); + $stmt->execute([':code' => $code]); + $order = $stmt->fetch(); + if (!$order) { + return null; + } + + $itemsStmt = $db->prepare("SELECT * FROM order_items WHERE order_id = :order_id"); + $itemsStmt->execute([':order_id' => $order['id']]); + $order['items'] = $itemsStmt->fetchAll(); + + return $order; + } + + public static function create(array $data, array $items): int + { + $db = Database::getConnection(); + $db->beginTransaction(); + + try { + $stmt = $db->prepare(" + INSERT INTO orders (order_code, customer_name, customer_phone, customer_email, province, city, address, postal_code, notes, shipping_method, payment_method, total_amount, discount_amount, final_amount, status) + VALUES (:order_code, :customer_name, :customer_phone, :customer_email, :province, :city, :address, :postal_code, :notes, :shipping_method, :payment_method, :total_amount, :discount_amount, :final_amount, :status) + "); + + $stmt->execute([ + ':order_code' => $data['order_code'], + ':customer_name' => $data['customer_name'], + ':customer_phone' => $data['customer_phone'], + ':customer_email' => $data['customer_email'] ?? '', + ':province' => $data['province'] ?? '', + ':city' => $data['city'] ?? '', + ':address' => $data['address'], + ':postal_code' => $data['postal_code'] ?? '', + ':notes' => $data['notes'] ?? '', + ':shipping_method' => $data['shipping_method'] ?? 'باربری / اتوبوس', + ':payment_method' => $data['payment_method'] ?? 'کارت به کارت', + ':total_amount' => $data['total_amount'], + ':discount_amount' => $data['discount_amount'] ?? 0, + ':final_amount' => $data['final_amount'], + ':status' => 'pending' + ]); + + $orderId = (int)$db->lastInsertId(); + + $itemStmt = $db->prepare(" + INSERT INTO order_items (order_id, product_id, product_name, quantity, unit_price, total_price, is_wholesale) + VALUES (:order_id, :product_id, :product_name, :quantity, :unit_price, :total_price, :is_wholesale) + "); + + foreach ($items as $item) { + $itemStmt->execute([ + ':order_id' => $orderId, + ':product_id' => $item['product_id'], + ':product_name' => $item['product_name'], + ':quantity' => $item['quantity'], + ':unit_price' => $item['unit_price'], + ':total_price' => $item['total_price'], + ':is_wholesale' => $item['is_wholesale'] ? 1 : 0 + ]); + } + + $db->commit(); + return $orderId; + } catch (\Throwable $e) { + $db->rollBack(); + throw $e; + } + } + + public static function updateStatus(int $id, string $status): bool + { + $db = Database::getConnection(); + $stmt = $db->prepare("UPDATE orders SET status = :status WHERE id = :id"); + return $stmt->execute([':id' => $id, ':status' => $status]); + } + + public static function getStats(): array + { + $db = Database::getConnection(); + $totalOrders = (int)$db->query("SELECT COUNT(*) FROM orders")->fetchColumn(); + $pendingOrders = (int)$db->query("SELECT COUNT(*) FROM orders WHERE status = 'pending'")->fetchColumn(); + $completedOrders = (int)$db->query("SELECT COUNT(*) FROM orders WHERE status = 'delivered'")->fetchColumn(); + $totalRevenue = (float)$db->query("SELECT COALESCE(SUM(final_amount), 0) FROM orders WHERE status != 'cancelled'")->fetchColumn(); + $newWholesale = (int)$db->query("SELECT COUNT(*) FROM wholesale_inquiries WHERE status = 'new'")->fetchColumn(); + $productsCount = (int)$db->query("SELECT COUNT(*) FROM products")->fetchColumn(); + + return [ + 'total_orders' => $totalOrders, + 'pending_orders' => $pendingOrders, + 'completed_orders' => $completedOrders, + 'total_revenue' => $totalRevenue, + 'new_wholesale' => $newWholesale, + 'products_count' => $productsCount + ]; + } +} diff --git a/src/Models/Product.php b/src/Models/Product.php new file mode 100644 index 0000000..3573bea --- /dev/null +++ b/src/Models/Product.php @@ -0,0 +1,157 @@ +prepare($query); + $stmt->execute($params); + return $stmt->fetchAll(); + } + + public static function featured(): array + { + $db = Database::getConnection(); + $stmt = $db->query("SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id WHERE p.is_featured = 1 ORDER BY p.id ASC LIMIT 8"); + return $stmt->fetchAll(); + } + + public static function findById(int $id): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id WHERE p.id = :id"); + $stmt->execute([':id' => $id]); + $row = $stmt->fetch(); + return $row ?: null; + } + + public static function findBySlug(string $slug): ?array + { + $db = Database::getConnection(); + $stmt = $db->prepare("SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id WHERE p.slug = :slug"); + $stmt->execute([':slug' => $slug]); + $row = $stmt->fetch(); + return $row ?: null; + } + + public static function calculateUnitPrice(array $product, int $quantity): array + { + $isWholesale = false; + $unitPrice = (float)$product['price']; + + if ((int)$product['is_wholesale_available'] === 1) { + if ($product['wholesale_tier2_qty'] > 0 && $quantity >= (int)$product['wholesale_tier2_qty']) { + $unitPrice = (float)$product['wholesale_tier2_price']; + $isWholesale = true; + } elseif ($product['wholesale_min_qty'] > 0 && $quantity >= (int)$product['wholesale_min_qty']) { + $unitPrice = (float)$product['wholesale_price']; + $isWholesale = true; + } + } + + return [ + 'unit_price' => $unitPrice, + 'total_price' => $unitPrice * $quantity, + 'is_wholesale' => $isWholesale, + 'discount_per_unit' => (float)$product['price'] - $unitPrice, + 'total_saved' => max(0, ((float)$product['price'] - $unitPrice) * $quantity) + ]; + } + + public static function create(array $data): int + { + $db = Database::getConnection(); + $stmt = $db->prepare(" + INSERT INTO products (category_id, name, slug, short_desc, full_desc, price, unit, stock, image, is_wholesale_available, wholesale_min_qty, wholesale_price, wholesale_tier2_qty, wholesale_tier2_price, is_featured) + VALUES (:category_id, :name, :slug, :short_desc, :full_desc, :price, :unit, :stock, :image, :is_wholesale_available, :wholesale_min_qty, :wholesale_price, :wholesale_tier2_qty, :wholesale_tier2_price, :is_featured) + "); + $stmt->execute([ + ':category_id' => $data['category_id'], + ':name' => $data['name'], + ':slug' => $data['slug'], + ':short_desc' => $data['short_desc'] ?? '', + ':full_desc' => $data['full_desc'] ?? '', + ':price' => $data['price'], + ':unit' => $data['unit'] ?? 'عدد', + ':stock' => $data['stock'] ?? 0, + ':image' => $data['image'] ?? '/assets/images/quail_live.svg', + ':is_wholesale_available' => $data['is_wholesale_available'] ?? 1, + ':wholesale_min_qty' => $data['wholesale_min_qty'] ?? 50, + ':wholesale_price' => $data['wholesale_price'] ?? 0, + ':wholesale_tier2_qty' => $data['wholesale_tier2_qty'] ?? 200, + ':wholesale_tier2_price' => $data['wholesale_tier2_price'] ?? 0, + ':is_featured' => $data['is_featured'] ?? 0 + ]); + return (int)$db->lastInsertId(); + } + + public static function update(int $id, array $data): bool + { + $db = Database::getConnection(); + $stmt = $db->prepare(" + UPDATE products SET + category_id = :category_id, + name = :name, + slug = :slug, + short_desc = :short_desc, + full_desc = :full_desc, + price = :price, + unit = :unit, + stock = :stock, + image = :image, + is_wholesale_available = :is_wholesale_available, + wholesale_min_qty = :wholesale_min_qty, + wholesale_price = :wholesale_price, + wholesale_tier2_qty = :wholesale_tier2_qty, + wholesale_tier2_price = :wholesale_tier2_price, + is_featured = :is_featured + WHERE id = :id + "); + return $stmt->execute([ + ':id' => $id, + ':category_id' => $data['category_id'], + ':name' => $data['name'], + ':slug' => $data['slug'], + ':short_desc' => $data['short_desc'] ?? '', + ':full_desc' => $data['full_desc'] ?? '', + ':price' => $data['price'], + ':unit' => $data['unit'] ?? 'عدد', + ':stock' => $data['stock'] ?? 0, + ':image' => $data['image'] ?? '/assets/images/quail_live.svg', + ':is_wholesale_available' => $data['is_wholesale_available'] ?? 1, + ':wholesale_min_qty' => $data['wholesale_min_qty'] ?? 50, + ':wholesale_price' => $data['wholesale_price'] ?? 0, + ':wholesale_tier2_qty' => $data['wholesale_tier2_qty'] ?? 200, + ':wholesale_tier2_price' => $data['wholesale_tier2_price'] ?? 0, + ':is_featured' => $data['is_featured'] ?? 0 + ]); + } + + public static function delete(int $id): bool + { + $db = Database::getConnection(); + $stmt = $db->prepare("DELETE FROM products WHERE id = :id"); + return $stmt->execute([':id' => $id]); + } +} diff --git a/src/Models/Setting.php b/src/Models/Setting.php new file mode 100644 index 0000000..f01de45 --- /dev/null +++ b/src/Models/Setting.php @@ -0,0 +1,37 @@ +prepare("SELECT value FROM settings WHERE key = :key"); + $stmt->execute([':key' => $key]); + $val = $stmt->fetchColumn(); + return $val !== false ? (string)$val : $default; + } + + public static function set(string $key, string $value): bool + { + $db = Database::getConnection(); + $stmt = $db->prepare("INSERT OR REPLACE INTO settings (key, value) VALUES (:key, :value)"); + return $stmt->execute([':key' => $key, ':value' => $value]); + } + + public static function getAll(): array + { + $db = Database::getConnection(); + $stmt = $db->query("SELECT key, value FROM settings"); + $results = []; + while ($row = $stmt->fetch()) { + $results[$row['key']] = $row['value']; + } + return $results; + } +} diff --git a/src/Models/WholesaleInquiry.php b/src/Models/WholesaleInquiry.php new file mode 100644 index 0000000..a7b7030 --- /dev/null +++ b/src/Models/WholesaleInquiry.php @@ -0,0 +1,43 @@ +query("SELECT * FROM wholesale_inquiries ORDER BY id DESC LIMIT " . (int)$limit); + return $stmt->fetchAll(); + } + + public static function create(array $data): int + { + $db = Database::getConnection(); + $stmt = $db->prepare(" + INSERT INTO wholesale_inquiries (customer_name, phone, company_name, product_requested, estimated_qty, city, notes, status) + VALUES (:customer_name, :phone, :company_name, :product_requested, :estimated_qty, :city, :notes, 'new') + "); + $stmt->execute([ + ':customer_name' => $data['customer_name'], + ':phone' => $data['phone'], + ':company_name' => $data['company_name'] ?? '', + ':product_requested' => $data['product_requested'], + ':estimated_qty' => $data['estimated_qty'] ?? '', + ':city' => $data['city'] ?? '', + ':notes' => $data['notes'] ?? '' + ]); + return (int)$db->lastInsertId(); + } + + public static function updateStatus(int $id, string $status): bool + { + $db = Database::getConnection(); + $stmt = $db->prepare("UPDATE wholesale_inquiries SET status = :status WHERE id = :id"); + return $stmt->execute([':id' => $id, ':status' => $status]); + } +} diff --git a/views/admin/dashboard.php b/views/admin/dashboard.php new file mode 100644 index 0000000..2f79bdb --- /dev/null +++ b/views/admin/dashboard.php @@ -0,0 +1,129 @@ + + + +
+
+
+ کل سفارش‌ها + +
+
+ +
+
+ +
+
+ سفارش‌های در انتظار تایید + +
+
+ +
+
+ +
+
+ استعلام‌های عمده جدید + +
+
+ +
+
+ +
+
+ مجموع فروش ثبت‌شده + +
+
+ +
+
+
+ +
+ +
+
+

سفارش‌های اخیر مشتریان

+ مشاهده همه +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
کد سفارشمشتریمبلغ کلوضعیتعملیات
هنوز سفارشی ثبت نشده است.
+ + + + + + + + + جزییات و فاکتور + +
+
+
+ + +
+
+

استعلام‌های اخیر عمده

+ همه +
+ +
+ +

استعلام جدیدی ثبت نشده است.

+ + +
+
+ + +
+

+
+ تماس: + +
+
+ + +
+
+
+ + diff --git a/views/admin/invoice.php b/views/admin/invoice.php new file mode 100644 index 0000000..0d4b558 --- /dev/null +++ b/views/admin/invoice.php @@ -0,0 +1,93 @@ + + + + + فاکتور فروش <?= $order['order_code'] ?> - <?= \Bildirchin\Config::APP_NAME ?> + + + + + +
+
+ + +
+ + +
+
+

+

تولید و عرضه صنعتی انواع بلدرچین، تخم، دان و تجهیزات

+

+

تلفن:

+
+
+ پیش‌فاکتور فروش + شماره: + تاریخ: +
+
+ + +
+
+ خریدار: +
+
+ شماره تماس: +
+
+ نشانی تحویل: - - +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ردیفشرح کالا / خدماتتعدادقیمت واحدمبلغ کل (تومان)
مبلغ نهایی قابل پرداخت:
+ + +
+
+ مهر و امضای فروشنده + مجتمع پرورشی بلدرچین زرین +
+
+ امضا و تایید خریدار +
+
+
+ + diff --git a/views/admin/layout_footer.php b/views/admin/layout_footer.php new file mode 100644 index 0000000..db6d328 --- /dev/null +++ b/views/admin/layout_footer.php @@ -0,0 +1,4 @@ + + + + diff --git a/views/admin/layout_header.php b/views/admin/layout_header.php new file mode 100644 index 0000000..7fdde9e --- /dev/null +++ b/views/admin/layout_header.php @@ -0,0 +1,114 @@ + + + + + + <?= isset($pageTitle) ? htmlspecialchars($pageTitle) . ' | ' : '' ?>پنل مدیریت مزرعه بلدرچین زرین + + + + + + + + + + + + + +
+ +
+
+

+
+
+ کاربر مدیر: + خروج +
+
+ + + + +
+ + +
+ + + +
+ + +
+ + + +
diff --git a/views/admin/login.php b/views/admin/login.php new file mode 100644 index 0000000..328987e --- /dev/null +++ b/views/admin/login.php @@ -0,0 +1,51 @@ + + + + + + ورود به مدیریت مزرعه بلدرچین زرین + + + + + + +
+
+
+ +
+

ورود به پنل مدیریت مزرعه

+

سامانه مدیریت سفارشات و محصولات بلدرچین زرین

+
+ + +
+ +
+ + +
+
+ + +
+ +
+ + +
+ + +
+ + +
+ + diff --git a/views/admin/order_detail.php b/views/admin/order_detail.php new file mode 100644 index 0000000..d70f531 --- /dev/null +++ b/views/admin/order_detail.php @@ -0,0 +1,96 @@ + + +
+
+
+ کد رهگیری سفارش: +

+ ثبت در تاریخ: +
+ +
+ + نسخه چاپی فاکتور + + + +
+ + + +
+
+
+ + +
+
+

مشخصات خریدار

+
نام و نام خانوادگی:
+
شماره تماس:
+
شیوه پرداخت:
+
روش ارسال:
+
+ +
+

آدرس و مقصد تحویل

+
استان و شهر: -
+
کد پستی:
+
آدرس کامل:

+ +
یادداشت:

+ +
+
+ + +
+
اقلام فاکتور
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
نام محصولتعدادقیمت واحدنوع نرخمجموع
+ نرخ عمده' : 'عادی' ?> +
مجموع کل:
+
+
+ + diff --git a/views/admin/orders.php b/views/admin/orders.php new file mode 100644 index 0000000..0752300 --- /dev/null +++ b/views/admin/orders.php @@ -0,0 +1,59 @@ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
کد سفارشخریدارشهر / آدرسمبلغ کلروش ارسال / پرداختوضعیتتاریخعملیات
سفارشی یافت نشد.
+ + + - + + + + + + + + + مشاهده فاکتور + +
+
+
+ + diff --git a/views/admin/products.php b/views/admin/products.php new file mode 100644 index 0000000..7141838 --- /dev/null +++ b/views/admin/products.php @@ -0,0 +1,177 @@ + + +
+

لیست محصولات فعال فروشگاه

+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
تصویر و عنواندستهقیمت تکیقیمت عمده (پله ۱)موجودیعملیات
+ +
+ + +
+
/ + 0 ? \Bildirchin\Helpers::formatPrice($p['wholesale_price']) : '-' ?> + +
+ +
+ + +
+
+
+
+
+ + + + + + + diff --git a/views/admin/settings.php b/views/admin/settings.php new file mode 100644 index 0000000..e7a5708 --- /dev/null +++ b/views/admin/settings.php @@ -0,0 +1,54 @@ + + +
+
+

اطلاعات عمومی مزرعه

+ +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +

اطلاعات واریز کارت به کارت

+ +
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+ + diff --git a/views/admin/wholesale_inquiries.php b/views/admin/wholesale_inquiries.php new file mode 100644 index 0000000..5631d52 --- /dev/null +++ b/views/admin/wholesale_inquiries.php @@ -0,0 +1,66 @@ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
نام متقاضیشماره همراهشرکت / فروشگاهمحصول مورد نظرحجم / تیراژشهر مقصدوضعیتعملیات
استعلامی ثبت نشده است.
+ + + + + + +
+ + + +
+
+ یادداشت متقاضی: +
+
+
+ + diff --git a/views/layout/footer.php b/views/layout/footer.php new file mode 100644 index 0000000..55469fe --- /dev/null +++ b/views/layout/footer.php @@ -0,0 +1,133 @@ + + + + + diff --git a/views/layout/header.php b/views/layout/header.php new file mode 100644 index 0000000..313430a --- /dev/null +++ b/views/layout/header.php @@ -0,0 +1,52 @@ + + + + + + <?= isset($pageTitle) ? htmlspecialchars($pageTitle) . ' | ' : '' ?><?= \Bildirchin\Config::APP_NAME ?> + + + + + + + + + + + + diff --git a/views/layout/navbar.php b/views/layout/navbar.php new file mode 100644 index 0000000..5170c8f --- /dev/null +++ b/views/layout/navbar.php @@ -0,0 +1,127 @@ + + +
+ +
+ مشاوره و سفارش: + پیگیری سفارش +
+
+ + +
+ +
+ + + + +
+
+
+ + +
+ +
+
+ + + +
+
+
+ + +
+ +
+
+ diff --git a/views/pages/404.php b/views/pages/404.php new file mode 100644 index 0000000..d8cf2c3 --- /dev/null +++ b/views/pages/404.php @@ -0,0 +1,18 @@ + + +
+ ۴۰۴ +

صفحه مورد نظر پیدا نشد!

+

آدرس وارد شده تغییر کرده یا حذف شده است.

+ + بازگشت به صفحه اصلی + +
+ + diff --git a/views/pages/about.php b/views/pages/about.php new file mode 100644 index 0000000..136aef2 --- /dev/null +++ b/views/pages/about.php @@ -0,0 +1,45 @@ + + +
+
+

درباره مجتمع پرورشی بلدرچین زرین

+

پیشگام در تولید صنعتی و سالم طیور با بیش از یک دهه سابقه درخشان

+
+
+ +
+
+

+ داستان شکل‌گیری و رسالت مزرعه +

+

+ مجتمع پرورشی بلدرچین زرین با هدف تامین پروتئین سالم، ارگانیک و باکیفیت برای سفره خانواده‌های ایرانی و تامین پایدار نیاز صنایع غذایی، رستوران‌ها و سالن‌داران در سال ۱۳۹۰ تاسیس شد. این مجموعه اکنون با بهره‌گیری از پیشرفته‌ترین سالن‌های تمام‌مکانیزه، خطوط مدرن بسته‌بندی تحت خلاء، و سالن‌های اختصاصی جوجه‌کشی با ظرفیت سالانه صدها هزار قطعه، به یکی از معتبرترین قطب‌های تولید بلدرچین در کشور تبدیل شده است. +

+ +
+
+ +

مجوز رسمی دامپزشکی

+

نظارت مداوم بهداشتی و قرنطینه استاندارد

+
+
+ +

ناوگان ارسال مجهز

+

ارسال کشتار روز با خودروهای سردخانه‌دار

+
+
+ +

اصلاح نژاد سنگین

+

بهترین راندمان گوشتی و تخم‌گذاری بالا

+
+
+
+
+ + diff --git a/views/pages/blog.php b/views/pages/blog.php new file mode 100644 index 0000000..353e2d6 --- /dev/null +++ b/views/pages/blog.php @@ -0,0 +1,48 @@ + + +
+
+

دانشنامه و مقالات آموزشی

+

راهنمای علمی و تجربی پرورش، تغذیه، بیماری‌ها و خواص محصولات بلدرچین

+
+
+ +
+
+ +
+ + <?= htmlspecialchars($art['title']) ?> + +
+
+
+ + + + نویسنده: +
+ + + +

+ +

+
+ + مطالعه کامل مقاله + + +
+
+ +
+
+ + diff --git a/views/pages/blog_detail.php b/views/pages/blog_detail.php new file mode 100644 index 0000000..7ed3bd9 --- /dev/null +++ b/views/pages/blog_detail.php @@ -0,0 +1,50 @@ + + +
+
+
+ بازگشت به مقالات + + تاریخ انتشار: + + +
+ +

+ +

+ +
+ +
+ +
+ + +
+ +
+ +
+ + +
+
+

نیاز به مشاوره جهت راه‌اندازی سالن یا خرید دان دارید؟

+

کارشناسان فنی مزرعه بلدرچین زرین به صورت رایگان پاسخگوی شما هستند.

+
+ + + تماس با مشاور + +
+
+
+ + diff --git a/views/pages/cart.php b/views/pages/cart.php new file mode 100644 index 0000000..7832e16 --- /dev/null +++ b/views/pages/cart.php @@ -0,0 +1,140 @@ + + +
+
+

سبد خرید شما

+

بررسی اقلام انتخابی و اعمال خودکار تخفیف‌های عمده‌فروشی

+
+
+ +
+ +
+
+ +
+

سبد خرید شما خالی است!

+

می‌توانید انواع بلدرچین، تخم خوراکی و نطفه‌دار، دان باکیفیت و ملزومات پرورش را از فروشگاه انتخاب کنید.

+ + مشاهده و خرید محصولات + +
+ +
+ +
+
+ اقلام انتخابی ( قلم) + تخفیف عمده خودکار فعال است +
+ +
+ +
+
+ +
+ + + +
+ قیمت واحد: + + + نرخ عمده + + +
+
+
+ + +
+
+ + + +
+ +
+ + 0): ?> + سود: + +
+ + + + +
+
+ +
+
+ + +
+

خلاصه پیش‌فاکتور

+ +
+
+ مجموع قیمت کالاها: + +
+ + 0): ?> +
+ تخفیف همکاری و عمده‌فروشی: + - +
+ + +
+ هزینه بسته‌بندی و ارسال: + محاسبه در مرحله بعد (بر اساس مقصد) +
+ +
+ مبلغ قابل پرداخت: + +
+
+ + + ادامه و تکمیل اطلاعات سفارش + + + + افزودن محصولات دیگر + +
+
+ +
+ + + + diff --git a/views/pages/checkout.php b/views/pages/checkout.php new file mode 100644 index 0000000..1b23117 --- /dev/null +++ b/views/pages/checkout.php @@ -0,0 +1,165 @@ + + +
+
+

تکمیل اطلاعات و ثبت سفارش

+

مشخصات تحویل‌گیرنده و انتخاب نحوه ارسال و پرداخت

+
+
+ +
+
+
+ +
+ +
+

+ ۱. مشخصات خریدار / تحویل‌گیرنده +

+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+
+ + +
+

+ ۲. روش ارسال +

+ +
+ + + + + +
+
+ + +
+

+ ۳. شیوه پرداخت +

+ +
+ + + +
+
+
+ + +
+

اقلام فاکتور

+ +
+ +
+
+ + × +
+ +
+ +
+ +
+
+ مجموع قیمت: + +
+ 0): ?> +
+ تخفیف عمده: + - +
+ +
+ مبلغ نهایی سفارش: + +
+
+ + +
+
+
+
+ + diff --git a/views/pages/contact.php b/views/pages/contact.php new file mode 100644 index 0000000..5710d41 --- /dev/null +++ b/views/pages/contact.php @@ -0,0 +1,89 @@ + + +
+
+ +
+ راه‌های ارتباطی +

پاسخگوی سوالات و سفارش‌های شما هستیم

+

+ جهت خرید حضوری، هماهنگی بارگیری، استعلام قیمت روز عمده یا مشاوره پرورش می‌توانید با شماره‌های زیر در ارتباط باشید. +

+ +
+
+ +
+ آدرس مجتمع پرورشی: + +
+
+ +
+ +
+ تلفن همراه و مدیریت فروش: + +
+
+ +
+ +
+ تلفن دفتر مرکزی: + +
+
+ +
+ +
+ واتساپ و ارسال فیش: + +
+
+
+
+ + +
+

ارسال پیام به مدیریت مزرعه

+

پیام‌ها در طول ساعات کاری بررسی و پاسخ داده می‌شوند.

+ +
+
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+ + +
+
+
+
+ + diff --git a/views/pages/home.php b/views/pages/home.php new file mode 100644 index 0000000..50e0e7a --- /dev/null +++ b/views/pages/home.php @@ -0,0 +1,391 @@ + + + +
+
+ +
+
+ +
+
+ + بزرگ‌ترین مجتمع پرورشی و اصلاح نژاد بلدرچین در کشور +
+ +

+ خرید مستقیم و بی‌واسطه
+ بلدرچین، تخم نطفه‌دار و خوراکی، دان و قفس +

+ +

+ تولید روزانه با بالاترین استانداردهای بهداشتی دامپزشکی. امکان خرید آنلاین در مقیاس خرد و ارائه بهترین قیمت‌های رقابتی برای سفارش‌های عمده، رستوران‌ها، هچری‌ها و سالن‌داران سراسر کشور. +

+ + + + + +
+ + پاسخگویی سریع و ثبت تلفنی: + +
+
+ + +
+
+
+ +
+ ظرفیت و توانمندی مزرعه +

تامین پایدار برای مشتریان سراسر کشور

+
+ +
+
+ ۵۰,۰۰۰+ + تولید ماهانه بلدرچین +
+
+ ۸۵٪ + + تضمین هچ تخم نطفه‌دار +
+
+ ۱۰۰٪ + کشتار روز و ارگانیک +
+
+ ۲۴ ساعته + ارسال با ماشین یخچال‌دار +
+
+ + + دریافت پیش‌فاکتور رسمی و خرید تیراژ + +
+
+
+
+
+ + +
+
+
+
+
+ +
+

قیمت مستقیم درب مزرعه

+

بدون واسطه و دلال با بهترین نرخ

+
+ +
+
+ +
+

مجوز و نظارت دامپزشکی

+

سلامت تضمین‌شده گله و کشتار بهداشتی

+
+ +
+
+ +
+

ارسال به تمام استان‌ها

+

بسته‌بندی تخصصی بدون افت تلفات

+
+ +
+
+ +
+

مشاوره رایگان پرورش

+

پشتیبانی فنی از دان تا جوجه‌کشی

+
+
+
+
+ + +
+
+ دسته‌بندی‌ها +

محصولات تولیدی و خدمات مزرعه

+
+ + +
+ + +
+
+
+
+ محصولات برگزیده +

پرفروش‌ترین‌های مزرعه

+
+ + مشاهده تمام محصولات + + +
+ +
+ +
+
+ + <?= htmlspecialchars($prod['name']) ?> + + + + + تخفیف عمده + + +
+ +
+
+ + + + +

+ +

+
+ +
+ +
+
+ قیمت مصرف‌کننده: + +
+ 0): ?> +
+ عمده (از ): + +
+ +
+ + + +
+
+
+ +
+
+
+ + +
+
+
+
+
+ + سیستم قیمت‌گذاری هوشمند عمده +
+

+ خرید عمده تناژ و تیراژ بالا
با تخفیف‌های ویژه مزرعه +

+

+ اگر صاحب رستوران، هتل، سالن پرورش، فروشگاه پروتئینی یا کارگاه جوجه‌کشی هستید، قیمت‌ها برای شما با نرخ عمده محاسبه می‌شود. همین حالا تیراژ مورد نیاز خود را در ماشین‌حساب روبرو انتخاب کنید. +

+ +
+ + +
+
+

+ محاسبه‌گر تخفیف تیراژ + محاسبه آنلاین +

+ +
+ + +
+ +
+
+ + واحد: عدد +
+
+ +
+
+ + +
+
+ نرخ هر واحد در این تیراژ: + - +
+
+ میزان سود و تخفیف شما: + - +
+
+ مبلغ کل فاکتور: + - +
+
+ + +
+
+
+
+
+ + +
+
+
+ دانشنامه و آموزش +

مقالات تخصصی پرورش بلدرچین

+
+ + مشاهده تمام مقالات + + +
+ +
+ + + +
+
+ + + + diff --git a/views/pages/order_success.php b/views/pages/order_success.php new file mode 100644 index 0000000..3cafa61 --- /dev/null +++ b/views/pages/order_success.php @@ -0,0 +1,65 @@ + + +
+
+
+ +
+ +
+ سفارش شما با موفقیت ثبت شد +

از حسن اعتماد و خرید شما سپاسگزاریم

+

کارشناسان مزرعه جهت هماهنگی و آماده‌سازی ارسال با شما تماس خواهند گرفت.

+
+ + +
+ کد رهگیری اختصاصی سفارش شما: + +

این کد را جهت پیگیری وضعیت سفارش ذخیره فرمایید.

+
+ + + +
+

+ اطلاعات حساب جهت واریز مبلغ فاکتور: +

+
+
+ شماره کارت: + +
+
+ به نام: + +
+
+ مبلغ قابل واریز: + +
+
+

+ پس از واریز، تصویر فیش را به همراه کد رهگیری به شماره واتساپ ارسال فرمایید. +

+
+ + + +
+
+ + diff --git a/views/pages/product_detail.php b/views/pages/product_detail.php new file mode 100644 index 0000000..01ade27 --- /dev/null +++ b/views/pages/product_detail.php @@ -0,0 +1,128 @@ + + +
+
+ خانه + / + محصولات + / + + / + +
+
+ +
+
+
+ +
+ <?= htmlspecialchars($product['name']) ?> +
+ + موجودی در انبار مزرعه: +
+
+ + +
+
+ +

+

+
+ + +
+
+ قیمت پایه (تکی): + / هر +
+ + +
+ + جدول تخفیف پلکانی عمده‌فروشی: + +
+ 0 && $product['wholesale_price'] > 0): ?> +
+
+ پله اول (از ) + سود شما: در هر واحد +
+ +
+ + + 0 && $product['wholesale_tier2_price'] > 0): ?> +
+
+ پله دوم (از ) + سود شما: در هر واحد +
+ +
+ +
+
+ +
+ + +
+ + +
+
+ + + +
+ + +
+
+ + +
+
ارسال فوری از سالن تولید
+
ضمانت کیفیت و سلامت کالا
+
صدور فاکتور معتبر و رسمی
+
مشاوره تخصصی قبل از خرید
+
+
+
+ + +
+

+ توضیحات و مشخصات فنی محصول +

+
+ +
+
+
+
+ + + + diff --git a/views/pages/products.php b/views/pages/products.php new file mode 100644 index 0000000..d3ced16 --- /dev/null +++ b/views/pages/products.php @@ -0,0 +1,105 @@ + + +
+
+
+
+

+ +

+

+ +

+
+ + + +
+
+
+ +
+ +
+ +

هیچ محصولی در این بخش یافت نشد.

+

می‌توانید سایر دسته‌بندی‌ها را مشاهده نمایید.

+ + مشاهده همه محصولات + +
+ +
+ +
+
+ + <?= htmlspecialchars($prod['name']) ?> + + + + + تخفیف عمده + + +
+ +
+
+ + + + +

+ +

+
+ +
+ +
+
+ قیمت مصرف‌کننده: + +
+ 0): ?> +
+ عمده (از ): + +
+ +
+ + + +
+
+
+ +
+ +
+ + diff --git a/views/pages/track_order.php b/views/pages/track_order.php new file mode 100644 index 0000000..327e7ed --- /dev/null +++ b/views/pages/track_order.php @@ -0,0 +1,110 @@ + + +
+
+
+ +
+

پیگیری وضعیت سفارش

+

کد رهگیری دریافت شده پس از ثبت سفارش را در کادر زیر وارد نمایید.

+
+ + +
+
+ + +
+
+ + + +
+ + ['label' => 'در انتظار بررسی و تایید مالی', 'step' => 1, 'color' => 'amber'], + 'confirmed' => ['label' => 'سفارش تایید شد', 'step' => 2, 'color' => 'sky'], + 'packing' => ['label' => 'در حال بسته‌بندی و آماده‌سازی در مزرعه', 'step' => 3, 'color' => 'indigo'], + 'shipped' => ['label' => 'تحویل باربری / ارسال شد', 'step' => 4, 'color' => 'emerald'], + 'delivered' => ['label' => 'تحویل داده شده', 'step' => 5, 'color' => 'emerald'], + 'cancelled' => ['label' => 'سفارش لغو شد', 'step' => 0, 'color' => 'rose'] + ]; + $currentStatus = $statusMap[$order['status']] ?? ['label' => $order['status'], 'step' => 1, 'color' => 'amber']; + ?> + +
+
+ شماره سفارش: + +
+
+ وضعیت فعلی: + + + +
+
+ + +
+
+ نام تحویل‌گیرنده: + +
+
+ شماره تماس: + +
+
+ تاریخ ثبت: + +
+
+ روش ارسال: + +
+
+ نحوه تسویه: + +
+
+ مبلغ کل فاکتور: + +
+
+ + +
+

اقلام سفارش داده شده:

+
+ +
+
+ + (تعداد: ) +
+ +
+ +
+
+
+ +
+ + سفارشی با این کد رهگیری در سامانه مزرعه ثبت نشده است. لطفاً از صحت کد وارد شده اطمینان حاصل فرمایید. +
+ + +
+ + diff --git a/views/pages/wholesale.php b/views/pages/wholesale.php new file mode 100644 index 0000000..2683bc0 --- /dev/null +++ b/views/pages/wholesale.php @@ -0,0 +1,138 @@ + + + +
+
+
+ + تامین پایدار برای رستوران‌ها، هایپرمارکت‌ها، مراکز جوجه‌کشی و پرورشی +
+

بخش فروش عمده، تناژ و تامین قراردادی

+

+ مزرعه بلدرچین زرین با ظرفیت تولید صنعتی، آماده عقد قراردادهای بلندمدت و ارسال منظم بار به سراسر ایران با نازل‌ترین نرخ درب مزرعه و مجوزهای رسمی دامپزشکی می‌باشد. +

+
+
+ +
+ +
+
+ جدول قیمت‌های همکاری +

لیست نرخ عمده و حداقل سفارش محصولات

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +
نام محصولقیمت تک‌فروشیپله اول عمدهپله دوم (تیراژ بالا)سفارش آنلاین
+ + + / + + از + + + از + + +
+
+
+
+ + +
+
+
+ فرم درخواست همکاری و استعلام +

ثبت درخواست پیش‌فاکتور و خرید تناژ

+

+ چنانچه حجم سفارش شما فراتر از مقادیر جدول بالاست یا نیاز به ارسال دوره‌ای (هفتگی/ماهانه) دارید، اطلاعات زیر را ثبت نمایید تا مسئول بازرگانی مزرعه در سریع‌ترین زمان ممکن با شما تماس بگیرد. +

+
+
تماس مستقیم بازرگانی:
+
پشتیبانی واتساپ:
+
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ + +
+
+
+
+
+ +