verifyRole('viewProduct'); $data['page_title'] = $this->pageTitle; $Product = new Products(); $data['motos'] = $Product->getActiveProductData(); $data['stores'] = $Stores->getActiveStore(); return $this->render_template('products/index', $data); } public function assign_store() { // Vérifie que la requête est bien une requête AJAX if (!$this->request->isAJAX()) { $response = Services::response(); $response->setStatusCode(404, 'Page Not Found')->send(); exit; } // Récupère les données POST sous format JSON $data = $this->request->getJSON(true); // Décodage en tableau associatif if (!isset($data['product_id']) || !isset($data['store_id'])) { return $this->response->setJSON([ 'success' => false, 'message' => 'Paramètres manquants.' ])->setStatusCode(400); } $product_id = $data['product_id']; $store_id = $data['store_id']; $productsModel = new Products(); // Appeler la méthode assignToStore pour mettre à jour la base de données $result = $productsModel->assignToStore($product_id, $store_id); // Répondre en JSON avec le résultat if ($result) { return $this->response->setJSON(['success' => true]); } else { return $this->response->setJSON(['success' => false, 'message' => 'Échec de la mise à jour.']); } } public function fetchProductData() { $result = ['data' => []]; $Products = new Products(); $Stores = new Stores(); function convertString($name) { return "$name"; } $data = $Products->getProductData(); foreach ($data as $key => $value) { // Gestion du nom du magasin if ($value['store_id'] == 0) { $store_name = "TOUS"; } else { $store_info = $Stores->getStoresData($value['store_id']); $store_name = $store_info && isset($store_info['name']) ? $store_info['name'] : "Inconnu"; } // Disponibilité $availability = ($value['qty'] > 0) ? 'En stock' : 'Rupture'; // Construction des boutons $buttons = ''; if (in_array('updateProduct', $this->permission ?? [])) { $buttons .= ''; } if (in_array('deleteProduct', $this->permission ?? [])) { $buttons .= ' '; } if (in_array('updateProduct', $this->permission ?? [])) { $buttons .= ' '; } if (in_array('updateProduct', $this->permission ?? [])) { $buttons .= ' '; } if (in_array('viewProduct', $this->permission ?? [])) { $buttons .= " "; } if (in_array('assignStore', $this->permission ?? [])) { $buttons .= ''; } $imagePath = 'assets/images/product_image/' . $value['image']; $imageHtml = $value['image'] ? '' : '
Aucune image
'; // Préparer les données pour DataTables (7 colonnes) $result['data'][$key] = [ $value['image'], convertString($value['sku']), $value['name'], $value['prix_vente'], $store_name, $availability, // <-- ici la disponibilité ajoutée $buttons ]; } return $this->response->setJSON($result); } public function create() { $Products = new Products(); $Brands = new Brands(); $Category = new Category(); $Stores = new Stores(); $Notification = new NotificationController(); $this->verifyRole('createProduct'); $data['page_title'] = $this->pageTitle; // die(var_dump(json_encode($this->request->getPost('categorie[]')))); // Validate form inputs $validation = \Config\Services::validation(); $validation->setRules([ 'nom_de_produit' => 'required', 'marque' => 'required', 'type' => 'required', 'numero_de_moteur' => 'required', 'prix' => 'required|numeric', 'price_vente' => 'required|numeric', 'puissance' => 'required', 'store' => 'required', 'availability' => 'required', 'price_min' => 'required|numeric', ]); if ($this->request->getMethod() === 'post' && $validation->withRequest($this->request)->run()) { // die(var_dump($this->request->getPost())); // Handle image upload $upload_image = $this->uploadImage(); // Prepare data for insertion $product_sold = false; $data = [ 'name' => $this->request->getPost('nom_de_produit'), 'sku' => $this->request->getPost('numero_de_serie'), 'price' => $this->request->getPost('prix'), 'qty' => 1, 'image' => $upload_image, 'description' => $this->request->getPost('description'), 'numero_de_moteur' => $this->request->getPost('numero_de_moteur'), 'marque' => $this->request->getPost('marque'), 'chasis' => $this->request->getPost('chasis'), 'store_id' => $this->request->getPost('store'), 'availability' => $this->request->getPost('availability'), 'prix_vente' => $this->request->getPost('price_vente'), 'date_arivage' => $this->request->getPost('datea'), 'puissance' => $this->request->getPost('puissance'), 'cler' => $this->request->getPost('cler'), 'categorie_id' => json_encode($this->request->getPost('categorie[]')), 'etats' => $this->request->getPost('etats'), 'infoManquekit' => $this->request->getPost('infoManquekit'), 'info' => $this->request->getPost('info'), 'infoManque' => $this->request->getPost('infoManque'), 'product_sold' => $product_sold, 'type'=> $this->request->getPost('type') ]; $store_id1 = (int)$this->request->getPost('store'); // Insert data into the database if ($Products->create($data)) { $data = [ 'product_id' => $Products->insertID(), 'prix_minimal' => $this->request->getPost('price_min'), ]; $Fourchette = new FourchettePrix(); $Fourchette->createFourchettePrix($data); session()->setFlashdata('success', 'Créé avec succès'); $Notification->createNotification("Un nouveau Produit a été crée", "COMMERCIALE",$store_id1,'product/'); return redirect()->to('/products'); } else { session()->setFlashdata('errors', 'Error occurred while creating the product'); return redirect()->to('products/create'); } } else { $data = [ 'stores' => $Stores->getActiveStore(), 'validation' => $validation, // Pass validation errors to the view 'page_title' => $this->pageTitle, 'marque' => $Brands->getActiveBrands(), 'categorie' => $Category->getActiveCategory(), ]; // Render the form view return $this->render_template('products/create', $data); } } private function uploadImage() { // Define the upload directory $uploadPath = 'assets/images/product_image'; // Ensure the directory exists if (!is_dir($uploadPath)) { mkdir($uploadPath, 0777, true); } // Check if the file is uploaded via the form $file = $this->request->getFile('product_image'); if ($file && $file->isValid() && !$file->hasMoved()) { // Generate a unique file name $newName = uniqid() . '.' . $file->getExtension(); // Move the file to the target directory $file->move($uploadPath, $newName); // Return the actual file name return $newName; } // If an error occurs, return the error message return $file ? $file->getErrorString() : 'No file was uploaded.'; } public function update(int $id) { $Products = new Products(); $Stores = new Stores(); $Category = new Category(); $this->verifyRole('updateProduct'); $data['page_title'] = $this->pageTitle; $Brands = new Brands(); // Validate form inputs $validation = \Config\Services::validation(); $validation->setRules([ 'nom_de_produit' => 'required', 'marque' => 'required', ]); if ($this->request->getMethod() === 'post' && $validation->withRequest($this->request)->run()) { $data = [ 'name' => $this->request->getPost('nom_de_produit'), 'sku' => $this->request->getPost('numero_de_serie'), 'price' => $this->request->getPost('price'), 'qty' => 1, 'description' => $this->request->getPost('description'), 'numero_de_moteur' => $this->request->getPost('numero_de_moteur'), 'marque' => $this->request->getPost('marque'), 'chasis' => $this->request->getPost('chasis'), 'store_id' => $this->request->getPost('store'), 'availability' => $this->request->getPost('availability'), 'prix_vente' => $this->request->getPost('price_vente'), 'date_arivage' => $this->request->getPost('datea'), 'puissance' => $this->request->getPost('puissance'), 'cler' => $this->request->getPost('cler'), 'categorie_id' => json_encode($this->request->getPost('categorie[]')), 'etats' => $this->request->getPost('etats'), 'infoManquekit' => $this->request->getPost('infoManquekit'), 'info' => $this->request->getPost('info'), 'infoManque' => $this->request->getPost('infoManque'), 'type'=> $this->request->getPost('type'), ]; // Check if a product image is uploaded if ($this->request->getFile('product_image')->isValid()) { $uploadImage = $this->uploadImage(); // Use the previously provided upload function $uploadData = ['image' => $uploadImage]; // Update the product with the uploaded image $Products->update($id, $uploadData); } if ($Products->updateProduct($data, $id)) { // die(var_dump('tonga eto')); session()->setFlashdata('success', 'Successfully updated'); return redirect()->to('/products'); } else { session()->setFlashdata('errors', 'Error occurred!!'); return redirect()->to('/produtcs/update/' . $id); } } else { $data = [ 'stores' => $Stores->getActiveStore(), 'validation' => $validation, // Pass validation errors to the view 'page_title' => $this->pageTitle, 'product_data' => $Products->getProductData($id), 'categorie' => $Category->getActiveCategory(), 'marque' => $Brands->getActiveBrands() ]; return $this->render_template('products/editbackup', $data); } } public function remove() { $this->verifyRole('deleteProduct'); $product_id = $this->request->getPost('product_id'); $response = []; $Products = new Products(); if ($product_id) { if ($Products->remove($product_id)) { $response['success'] = true; $response['messages'] = "Successfully removed"; } else { $response['success'] = false; $response['messages'] = "Error in the database while removing the product information"; } } else { $response['success'] = false; $response['messages'] = "Refersh the page again!!"; } // Return JSON response return $this->response->setJSON($response); } public function createByExcel() { $this->verifyRole("createProduct"); try { $file = $this->request->getFile('excel_product'); if (!$file || !$file->isValid()) { return $this->response->setJSON([ 'success' => false, 'messages' => "Fichier invalide ou non reçu" ]); } $ext = strtolower($file->getClientExtension()); if (!in_array($ext, ['xls', 'xlsx'])) { return $this->response->setJSON([ 'success' => false, 'messages' => "Seuls les fichiers Excel (.xls, .xlsx) sont acceptés" ]); } $spreadsheet = IOFactory::load($file->getTempName()); $sheet = $spreadsheet->getActiveSheet(); $rows = $sheet->toArray(); if (count($rows) <= 1) { return $this->response->setJSON([ 'success' => false, 'messages' => "Le fichier ne contient pas de données" ]); } // Récupérer les en-têtes $headers = array_shift($rows); $headers = array_map('strtolower', $headers); // Mapping des colonnes Excel vers les champs de la base $columnMapping = [ 'n° série' => 'sku', 'marque' => 'marque', 'désignation' => 'name', 'fournisseur' => 'info', // À adapter selon votre besoin 'date d\'arrivage' => 'date_arivage', 'n° moteur' => 'numero_de_moteur', 'châssis' => 'chasis', 'puissance' => 'puissance', 'clé' => 'cler', 'prix d\'achat' => 'price', 'prix ar' => 'prix_vente', 'catégories' => 'categorie_id', 'magasin' => 'store_id', 'disponibilité' => 'availability', 'état' => 'etats', 'pièce manquant' => 'infoManque', 'type' => 'type', ]; $ProductsModel = new Products(); $BrandsModel = new Brands(); $StoresModel = new Stores(); $CategoryModel = new Category(); $countInserted = 0; foreach ($rows as $row) { if (empty(array_filter($row))) continue; // Ignore les lignes vides $data = [ 'is_piece' => 0, 'product_sold' => 0, 'qty' => 1 ]; // Mapper chaque colonne foreach ($headers as $index => $header) { $header = trim($header); if (isset($columnMapping[$header]) && isset($row[$index])) { $field = $columnMapping[$header]; $value = trim($row[$index]); // Traitements spécifiques pour certains champs switch ($field) { case 'marque': // Chercher ou créer la marque $brand = $BrandsModel->where('name', $value)->first(); if (!$brand) { $brandId = $BrandsModel->insert(['name' => $value, 'active' => 1]); } else { $brandId = $brand['id']; } $data[$field] = $brandId; break; case 'store_id': // Gestion du magasin if ($value == 'TOUS') { $data[$field] = 0; } else { $store = $StoresModel->where('name', $value)->first(); $data[$field] = $store ? $store['id'] : 0; } break; case 'date_arivage': // Convertir la date Excel en format MySQL if (is_numeric($value)) { $data[$field] = date('Y-m-d', \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimestamp($value)); } else { $data[$field] = date('Y-m-d', strtotime($value)); } break; case 'price': // Nettoyer "1 900 000 Ar" → 1900000.00 $cleanedValue = str_replace(['Ar', ' ', ','], '', $value); $data[$field] = (float)$cleanedValue; break; default: $data[$field] = $value; } } } // Insertion if (!empty($data['name'])) { if ($ProductsModel->insert($data)) { $countInserted++; } } } return $this->response->setJSON([ 'success' => true, 'messages' => "$countInserted produits importés avec succès" ]); } catch (\Exception $e) { return $this->response->setJSON([ 'success' => false, 'messages' => "Erreur lors de l'import: " . $e->getMessage() ]); } } }