verifyRole('viewEncaissement'); $session = session(); $user = $session->get('user'); $data['page_title'] = $this->pageTitle; $data['user_role'] = $user['group_name']; $data['user_permission'] = $this->permission; // Récupérer les magasins pour le filtre $storeModel = new Stores(); $data['stores'] = $storeModel->getActiveStore(); return $this->render_template('autres_encaissements/index', $data); } /** * Ajouter un encaissement */ public function create() { if ($this->request->getMethod() !== 'post') { return $this->response->setJSON([ 'success' => false, 'messages' => 'Méthode non autorisée' ]); } try { $this->verifyRole('createEncaissement'); $session = session(); $user = $session->get('user'); // Validation des données $validation = \Config\Services::validation(); $validation->setRules([ 'type_encaissement' => 'required', 'montant' => 'required|decimal', 'mode_paiement' => 'required|in_list[Espèces,MVola,Virement Bancaire]', 'commentaire' => 'permit_empty|string' ]); if (!$validation->withRequest($this->request)->run()) { return $this->response->setJSON([ 'success' => false, 'messages' => $validation->getErrors() ]); } $encaissementModel = new AutresEncaissements(); $Notification = new NotificationController(); $typeEncaissement = $this->request->getPost('type_encaissement'); $autreType = $this->request->getPost('autre_type'); // Si "Autre" est sélectionné, utiliser le champ texte $finalType = ($typeEncaissement === 'Autre' && !empty($autreType)) ? $autreType : $typeEncaissement; $data = [ 'type_encaissement' => $finalType, 'autre_type' => $autreType, 'montant' => $this->request->getPost('montant'), 'mode_paiement' => $this->request->getPost('mode_paiement'), 'commentaire' => $this->request->getPost('commentaire'), 'user_id' => $user['id'], 'store_id' => $user['store_id'] ]; if ($encaissementId = $encaissementModel->insert($data)) { // ✅ Récupérer tous les stores pour les notifications $db = \Config\Database::connect(); $storesQuery = $db->table('stores')->select('id')->get(); $allStores = $storesQuery->getResultArray(); $montantFormate = number_format((float)$this->request->getPost('montant'), 0, ',', ' '); $notificationMessage = "Nouvel encaissement {$finalType} créé par {$user['firstname']} {$user['lastname']} - Montant: {$montantFormate} Ar"; // ✅ Envoyer notification à DAF, Direction et SuperAdmin de TOUS les stores foreach ($allStores as $store) { $storeId = (int)$store['id']; // Notification pour DAF $Notification->createNotification( $notificationMessage, "DAF", $storeId, 'encaissements' ); // Notification pour Direction $Notification->createNotification( $notificationMessage, "Direction", $storeId, 'encaissements' ); // Notification pour SuperAdmin $Notification->createNotification( $notificationMessage, "SuperAdmin", $storeId, 'encaissements' ); } log_message('info', "✅ Encaissement {$encaissementId} créé - Notifications envoyées à DAF/Direction/SuperAdmin de tous les stores"); return $this->response->setJSON([ 'success' => true, 'messages' => 'Encaissement enregistré avec succès' ]); } return $this->response->setJSON([ 'success' => false, 'messages' => 'Erreur lors de l\'enregistrement' ]); } catch (\Exception $e) { log_message('error', "Erreur création encaissement: " . $e->getMessage()); return $this->response->setJSON([ 'success' => false, 'messages' => 'Une erreur interne est survenue: ' . $e->getMessage() ]); } } /** * Modifier un encaissement */ public function update($id) { try { $this->verifyRole('updateEncaissement'); $session = session(); $user = $session->get('user'); $encaissementModel = new AutresEncaissements(); $Notification = new NotificationController(); // Récupérer l'ancien encaissement pour comparaison $oldEncaissement = $encaissementModel->find($id); if (!$oldEncaissement) { return $this->response->setJSON([ 'success' => false, 'messages' => 'Encaissement non trouvé' ]); } $typeEncaissement = $this->request->getPost('type_encaissement'); $autreType = $this->request->getPost('autre_type'); $finalType = ($typeEncaissement === 'Autre' && !empty($autreType)) ? $autreType : $typeEncaissement; $data = [ 'type_encaissement' => $finalType, 'autre_type' => $autreType, 'montant' => $this->request->getPost('montant'), 'mode_paiement' => $this->request->getPost('mode_paiement'), 'commentaire' => $this->request->getPost('commentaire') ]; if ($encaissementModel->update($id, $data)) { // ✅ Envoyer notification de modification à tous les stores $db = \Config\Database::connect(); $storesQuery = $db->table('stores')->select('id')->get(); $allStores = $storesQuery->getResultArray(); $montantFormate = number_format((float)$this->request->getPost('montant'), 0, ',', ' '); $ancienMontant = number_format((float)$oldEncaissement['montant'], 0, ',', ' '); $notificationMessage = "Encaissement {$finalType} modifié par {$user['firstname']} {$user['lastname']} - Ancien montant: {$ancienMontant} Ar → Nouveau: {$montantFormate} Ar"; foreach ($allStores as $store) { $storeId = (int)$store['id']; $Notification->createNotification( $notificationMessage, "DAF", $storeId, 'encaissements' ); $Notification->createNotification( $notificationMessage, "Direction", $storeId, 'encaissements' ); $Notification->createNotification( $notificationMessage, "SuperAdmin", $storeId, 'encaissements' ); } log_message('info', "✅ Encaissement {$id} modifié - Notifications envoyées"); return $this->response->setJSON([ 'success' => true, 'messages' => 'Encaissement modifié avec succès' ]); } return $this->response->setJSON([ 'success' => false, 'messages' => 'Erreur lors de la modification' ]); } catch (\Exception $e) { log_message('error', 'Erreur dans update(): ' . $e->getMessage()); return $this->response->setJSON([ 'success' => false, 'messages' => 'Erreur serveur: ' . $e->getMessage() ]); } } /** * Supprimer un encaissement */ public function delete($id) { try { $this->verifyRole('deleteEncaissement'); $session = session(); $user = $session->get('user'); $encaissementModel = new AutresEncaissements(); $Notification = new NotificationController(); // Récupérer l'encaissement avant suppression pour la notification $encaissement = $encaissementModel->find($id); if (!$encaissement) { return $this->response->setJSON([ 'success' => false, 'messages' => 'Encaissement non trouvé' ]); } if ($encaissementModel->delete($id)) { // ✅ Envoyer notification de suppression à tous les stores $db = \Config\Database::connect(); $storesQuery = $db->table('stores')->select('id')->get(); $allStores = $storesQuery->getResultArray(); $montantFormate = number_format((float)$encaissement['montant'], 0, ',', ' '); $type = $encaissement['type_encaissement']; $notificationMessage = "⚠️ Encaissement {$type} supprimé par {$user['firstname']} {$user['lastname']} - Montant: {$montantFormate} Ar"; foreach ($allStores as $store) { $storeId = (int)$store['id']; $Notification->createNotification( $notificationMessage, "DAF", $storeId, 'encaissements' ); $Notification->createNotification( $notificationMessage, "Direction", $storeId, 'encaissements' ); $Notification->createNotification( $notificationMessage, "SuperAdmin", $storeId, 'encaissements' ); } log_message('info', "✅ Encaissement {$id} supprimé - Notifications envoyées"); return $this->response->setJSON([ 'success' => true, 'messages' => 'Encaissement supprimé avec succès' ]); } return $this->response->setJSON([ 'success' => false, 'messages' => 'Erreur lors de la suppression' ]); } catch (\Exception $e) { log_message('error', 'Erreur dans delete(): ' . $e->getMessage()); return $this->response->setJSON([ 'success' => false, 'messages' => 'Erreur serveur: ' . $e->getMessage() ]); } } /** * Récupérer les données pour DataTables */ public function fetchEncaissements() { try { $this->verifyRole('viewEncaissement'); $session = session(); $user = $session->get('user'); $encaissementModel = new AutresEncaissements(); // Récupérer les filtres $startDate = $this->request->getGet('startDate'); $endDate = $this->request->getGet('endDate'); $storeId = $this->request->getGet('store_id'); // Si l'utilisateur n'est pas admin, limiter à son magasin if (!in_array($user['group_name'], ['SuperAdmin', 'DAF', 'Direction'])) { $storeId = $user['store_id']; } $encaissements = $encaissementModel->getEncaissementsWithDetails($storeId); // Filtrer par dates if ($startDate || $endDate) { $encaissements = array_filter($encaissements, function($item) use ($startDate, $endDate) { $itemDate = date('Y-m-d', strtotime($item['created_at'])); if ($startDate && $itemDate < $startDate) { return false; } if ($endDate && $itemDate > $endDate) { return false; } return true; }); } $result = []; foreach ($encaissements as $item) { // Construire les boutons avec permissions $buttons = ''; if (in_array('viewEncaissement', $this->permission)) { $buttons .= ' '; } if (in_array('updateEncaissement', $this->permission)) { $buttons .= ' '; } if (in_array('deleteEncaissement', $this->permission)) { $buttons .= ''; } // ✅ Badge coloré pour le mode de paiement $badgeClass = match($item['mode_paiement']) { 'Espèces' => 'success', 'MVola' => 'warning', 'Virement Bancaire' => 'info', default => 'default' }; $modePaiementBadge = '' . $item['mode_paiement'] . ''; $result[] = [ $item['id'], $item['type_encaissement'], number_format($item['montant'], 0, '.', ' ') . ' Ar', $modePaiementBadge, // ✅ NOUVELLE COLONNE $item['commentaire'] ?: 'Aucun', $item['user_name'] ?: 'N/A', $item['store_name'] ?: 'N/A', date('d/m/Y H:i', strtotime($item['created_at'])), $buttons ]; } return $this->response->setJSON(['data' => $result]); } catch (\Exception $e) { log_message('error', 'Erreur dans fetchEncaissements(): ' . $e->getMessage()); return $this->response->setJSON(['data' => []]); } } /** * Récupérer les détails d'un encaissement */ public function getDetails($id) { try { $this->verifyRole('viewEncaissement'); $encaissementModel = new AutresEncaissements(); $encaissement = $encaissementModel->getEncaissementById($id); if ($encaissement) { return $this->response->setJSON([ 'success' => true, 'data' => $encaissement ]); } return $this->response->setJSON([ 'success' => false, 'message' => 'Encaissement non trouvé' ]); } catch (\Exception $e) { log_message('error', 'Erreur dans getDetails(): ' . $e->getMessage()); return $this->response->setJSON([ 'success' => false, 'message' => 'Erreur serveur' ]); } } /** * Récupérer un encaissement pour édition */ public function getEncaissement($id) { try { $this->verifyRole('updateEncaissement'); $encaissementModel = new AutresEncaissements(); $encaissement = $encaissementModel->find($id); if ($encaissement) { return $this->response->setJSON([ 'success' => true, 'data' => $encaissement ]); } return $this->response->setJSON([ 'success' => false, 'message' => 'Encaissement non trouvé' ]); } catch (\Exception $e) { log_message('error', 'Erreur dans getEncaissement(): ' . $e->getMessage()); return $this->response->setJSON([ 'success' => false, 'message' => 'Erreur serveur' ]); } } /** * Récupérer les statistiques */ public function getStatistics() { try { $this->verifyRole('viewEncaissement'); $session = session(); $user = $session->get('user'); $encaissementModel = new AutresEncaissements(); $startDate = $this->request->getGet('startDate'); $endDate = $this->request->getGet('endDate'); $storeId = $this->request->getGet('store_id'); // ✅ LOG pour débogage log_message('info', "📊 getStatistics appelé - Dates: {$startDate} à {$endDate}, Store: {$storeId}"); // Si l'utilisateur n'est pas admin, limiter à son magasin if (!in_array($user['group_name'], ['SuperAdmin', 'DAF', 'Direction'])) { $storeId = $user['store_id']; } // ✅ IMPORTANT : Convertir $storeId en NULL si vide $storeIdFilter = (!empty($storeId) && $storeId !== '') ? (int)$storeId : null; // Récupérer les totaux $totalMontant = $encaissementModel->getTotalEncaissements($storeIdFilter, $startDate, $endDate); $totalCount = $encaissementModel->getTotalCount($storeIdFilter, $startDate, $endDate); $todayCount = $encaissementModel->getTodayCount($storeIdFilter); // Récupérer les totaux par mode de paiement $totauxParMode = $encaissementModel->getTotalEncaissementsByMode($storeIdFilter, $startDate, $endDate); // Statistiques par type $statsByType = $encaissementModel->getStatsByType($storeIdFilter, $startDate, $endDate); // ✅ LOG pour vérifier les valeurs log_message('info', "✅ Résultats - Total: {$totalMontant}, Count: {$totalCount}, Today: {$todayCount}"); return $this->response->setJSON([ 'success' => true, 'total_montant' => number_format($totalMontant, 0, ',', ' ') . ' Ar', 'total_count' => $totalCount, 'today_count' => $todayCount, 'total_espece' => number_format($totauxParMode['total_espece'], 0, ',', ' ') . ' Ar', 'total_mvola' => number_format($totauxParMode['total_mvola'], 0, ',', ' ') . ' Ar', 'total_virement' => number_format($totauxParMode['total_virement'], 0, ',', ' ') . ' Ar', 'stats_by_type' => $statsByType, // ✅ Ajouter ces infos pour débogage 'debug' => [ 'store_id' => $storeIdFilter, 'start_date' => $startDate, 'end_date' => $endDate ] ]); } catch (\Exception $e) { log_message('error', '❌ Erreur dans getStatistics(): ' . $e->getMessage()); return $this->response->setJSON([ 'success' => false, 'total_montant' => '0 Ar', 'total_count' => 0, 'today_count' => 0, 'total_espece' => '0 Ar', 'total_mvola' => '0 Ar', 'total_virement' => '0 Ar', 'stats_by_type' => [], 'error' => $e->getMessage() ]); } } }