Browse Source

debug:

notification
ajout commande
master
OmegaRak 6 hours ago
parent
commit
a18ccbf34b
  1. 3
      app/Config/Routes.php
  2. 2
      app/Config/View.php
  3. 82
      app/Controllers/AutresEncaissementsController.php
  4. 93
      app/Controllers/AvanceController.php
  5. 6
      app/Controllers/AvanceControlleur.php
  6. 2
      app/Controllers/CompanyController.php
  7. 6
      app/Controllers/GroupController.php
  8. 23
      app/Controllers/NotificationController.php
  9. 136
      app/Controllers/OrderController.php
  10. 11
      app/Controllers/ProductCOntroller.php
  11. 86
      app/Controllers/RecouvrementController.php
  12. 110
      app/Controllers/RemiseController.php
  13. 2
      app/Controllers/SecuriteController.php
  14. 32
      app/Controllers/SortieCaisseController.php
  15. 6
      app/Controllers/UserController.php
  16. 18
      app/Models/Groups.php
  17. 73
      app/Views/groups/edit.php
  18. 33
      app/Views/orders/create.php
  19. 65
      app/Views/templates/header_menu.php

3
app/Config/Routes.php

@ -22,7 +22,6 @@ use App\Controllers\ReservationController;
use App\Controllers\SecuriteController;
use App\Controllers\SortieCaisseController;
use App\Controllers\RemiseController;
use App\Controllers\PerformanceController;
/**
* auth route
* the option array filter make a filter,
@ -183,7 +182,7 @@ $routes->group('', ['filter' => 'auth'], function ($routes) {
$routes->get('update/(:num)', [ProductCOntroller::class, 'update']);
$routes->post('update/(:num)', [ProductCOntroller::class, 'update']);
$routes->post('remove', [ProductCOntroller::class, 'remove']);
$routes->get('generateqrcode/(:num)', [QrCodeCOntroller::class, 'generate']);
$routes->get('generateqrcode/(:num)', [QrCodeController::class, 'generate']);
$routes->post('assign_store', [ProductCOntroller::class, 'assign_store']);
$routes->post('createByExcel', [ProductCOntroller::class, 'createByExcel']);
$routes->post('checkProductAvailability', [ProductCOntroller::class, 'checkProductAvailability']);

2
app/Config/View.php

@ -59,4 +59,6 @@ class View extends BaseView
* @var list<class-string<ViewDecoratorInterface>>
*/
public array $decorators = [];
public string $appOverridesFolder = APPPATH . 'Views/';
}

82
app/Controllers/AutresEncaissementsController.php

@ -41,7 +41,7 @@ class AutresEncaissementsController extends AdminController
*/
public function create()
{
if ($this->request->getMethod() !== 'post') {
if (strtolower($this->request->getMethod()) !== 'post') {
return $this->response->setJSON([
'success' => false,
'messages' => 'Méthode non autorisée'
@ -103,35 +103,9 @@ class AutresEncaissementsController extends AdminController
$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'
);
}
$Notification->notifyGroupsByPermissionAllStores('notifEncaissement', $notificationMessage, 'encaissements');
log_message('info', "✅ Encaissement {$encaissementId} créé - Notifications envoyées à DAF/Direction/SuperAdmin de tous les stores");
log_message('info', "✅ Encaissement {$encaissementId} créé - Notifications envoyées");
return $this->response->setJSON([
'success' => true,
@ -204,30 +178,7 @@ class AutresEncaissementsController extends AdminController
$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'
);
}
$Notification->notifyGroupsByPermissionAllStores('notifEncaissement', $notificationMessage, 'encaissements');
log_message('info', "✅ Encaissement {$id} modifié - Notifications envoyées");
@ -287,30 +238,7 @@ class AutresEncaissementsController extends AdminController
$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'
);
}
$Notification->notifyGroupsByPermissionAllStores('notifEncaissement', $notificationMessage, 'encaissements');
log_message('info', "✅ Encaissement {$id} supprimé - Notifications envoyées");

93
app/Controllers/AvanceController.php

@ -318,28 +318,11 @@ public function validateAvance()
$customerName = $avance['customer_name'];
$avanceNumber = str_pad($avance['avance_id'], 5, '0', STR_PAD_LEFT);
// Notifier le commercial
$Notification->createNotification(
"✅ Votre avance N°{$avanceNumber} pour le client {$customerName} a été validée par la caissière",
"COMMERCIALE",
(int)$users['store_id'],
'avances'
);
// Notifier Direction/DAF
$Notification->createNotification(
"La caissière a validé l'avance N°{$avanceNumber} créée par un commercial",
"Direction",
(int)$users['store_id'],
'avances'
);
// Notifier les commerciaux
$Notification->notifyGroupsByPermission('notifRemise', "✅ Votre avance N°{$avanceNumber} pour le client {$customerName} a été validée par la caissière", (int)$users['store_id'], 'avances');
$Notification->createNotification(
"La caissière a validé l'avance N°{$avanceNumber} créée par un commercial",
"DAF",
(int)$users['store_id'],
'avances'
);
// Notifier les groupes ayant updateAvance
$Notification->notifyGroupsByPermission('notifAvance', "La caissière a validé l'avance N°{$avanceNumber} créée par un commercial", (int)$users['store_id'], 'avances');
return $this->response->setJSON([
'success' => true,
@ -565,7 +548,7 @@ public function validateAvance()
{
$this->verifyRole('createAvance');
if ($this->request->getMethod() !== 'post') {
if (strtolower($this->request->getMethod()) !== 'post') {
return $this->response->setJSON([
'success' => false,
'messages' => 'Méthode non autorisée'
@ -672,43 +655,12 @@ public function validateAvance()
$notificationMessage = "Nouvelle avance {$typeAvanceLabel} créée par {$users['firstname']} {$users['lastname']} - Client: {$customerName} - Montant: {$avanceAmount} 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,
'avances'
);
// Notification pour Direction
$Notification->createNotification(
$notificationMessage,
"Direction",
$storeId,
'avances'
);
// Notification pour SuperAdmin
$Notification->createNotification(
$notificationMessage,
"SuperAdmin",
$storeId,
'avances'
);
}
// ✅ Notifier tous les groupes ayant updateAvance de TOUS les stores
$Notification->notifyGroupsByPermissionAllStores('notifAvance', $notificationMessage, 'avances');
// ✅ Notification à la Caissière UNIQUEMENT du store concerné (si l'utilisateur est COMMERCIALE)
if ($this->isCommerciale($users)) {
$Notification->createNotification(
'Une nouvelle avance a été créée par un commercial',
"Caissière",
(int)$users['store_id'],
'avances'
);
$Notification->notifyGroupsByPermission('notifSortieCaisse', 'Une nouvelle avance a été créée par un commercial', (int)$users['store_id'], 'avances');
}
log_message('info', "✅ Avance {$avance_id} créée - Notifications envoyées à DAF/Direction/SuperAdmin de tous les stores");
@ -737,7 +689,7 @@ public function validateAvance()
{
$this->verifyRole('updateAvance');
if ($this->request->getMethod() !== 'post') {
if (strtolower($this->request->getMethod()) !== 'post') {
return $this->response->setJSON([
'success' => false,
'messages' => 'Méthode non autorisée'
@ -901,12 +853,7 @@ public function validateAvance()
}
// ✅ NOTIFICATION (modification simple)
$Notification->createNotification(
'Une avance a été modifiée',
"Caissière",
(int)$users['store_id'],
'avances'
);
$Notification->notifyGroupsByPermission('notifSortieCaisse', 'Une avance a été modifiée', (int)$users['store_id'], 'avances');
return $this->response->setJSON([
'success' => true,
@ -1756,23 +1703,9 @@ public function notifyPrintInvoice()
$customerName = $avance['customer_name'];
$avanceNumber = str_pad($avance['avance_id'], 5, '0', STR_PAD_LEFT);
$Notification->createNotification(
"La caissière a imprimé la facture N°{$avanceNumber} pour le client {$customerName}",
"Direction",
(int)$users['store_id'],
'avances'
);
$Notification->createNotification(
"Il y a une avance N°{$avanceNumber} pour le client {$customerName}",
"DAF",
(int)$users['store_id'],
'avances'
);
$Notification->createNotification(
"Il y a une avance N°{$avanceNumber} pour le client {$customerName}",
"SuperAdmin",
$Notification->notifyGroupsByPermission(
'updateAvance',
"La caissière a imprimé la facture avance N°{$avanceNumber} pour le client {$customerName}",
(int)$users['store_id'],
'avances'
);

6
app/Controllers/AvanceControlleur.php

@ -100,7 +100,7 @@ class AvanceController extends AdminController
$Products = new Products();
$Notification = New NotificationController();
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
if (strtolower($this->request->getMethod()) === 'post' && $validation->run($validationData)) {
$session = session();
$users = $session->get('user');
@ -120,7 +120,7 @@ class AvanceController extends AdminController
$posts = $products;
if($avance_id = $Avance->createAvance($data)){
$Notification->createNotification('Une avance a été créé', "Conseil",$users['store_id'], 'avance');
$Notification->notifyGroupsByPermission('notifAvance', 'Une avance a été créé', $users['store_id'], 'avance');
return $this->response->setJSON([
'success' => true,
'messages' => 'Avance créé avec succès !'
@ -143,7 +143,7 @@ class AvanceController extends AdminController
$Products = new Products();
$Avance = new Avance();
if ($this->request->getMethod() === 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
$data = [
'customer_name' => $this->request->getPost('customer_name_avance'),
'customer_address'=> $this->request->getPost('customer_address_avance'),

2
app/Controllers/CompanyController.php

@ -29,7 +29,7 @@ class CompanyController extends AdminController
$Company = new Company();
// die(var_dump($validation->getErrors()));
if ($this->request->getMethod() == 'post' && $validation->withRequest($this->request)->run()) {
if (strtolower($this->request->getMethod()) === 'post' && $validation->withRequest($this->request)->run()) {
// If the form is valid
$data = [
'company_name' => $this->request->getPost('company_name'),

6
app/Controllers/GroupController.php

@ -45,7 +45,7 @@ class GroupController extends AdminController
]);
// Check if form validation is successful
if ($this->request->getMethod() == 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
if ($validation->withRequest($this->request)->run()) {
@ -93,7 +93,7 @@ class GroupController extends AdminController
'group_name' => 'required',
]);
if ($this->request->getMethod() === 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
if ($validation->withRequest($this->request)->run()) {
// Validation passed
@ -149,7 +149,7 @@ class GroupController extends AdminController
}
// Vérifier si c'est une requête POST avec confirmation
if ($this->request->getMethod() === 'post' && $this->request->getPost('confirm')) {
if (strtolower($this->request->getMethod()) === 'post' && $this->request->getPost('confirm')) {
// Supprimer d'abord toutes les associations dans user_group
$groupsModel->removeUsersFromGroup($id);

23
app/Controllers/NotificationController.php

@ -3,6 +3,8 @@
namespace App\Controllers;
use App\Models\Notification;
use App\Models\Groups;
use App\Models\Stores;
class NotificationController extends AdminController
{
@ -44,6 +46,27 @@ class NotificationController extends AdminController
$Notification->insertNotification($data);
}
// Notifier tous les groupes ayant une permission donnée, pour un store spécifique
public function notifyGroupsByPermission(string $permission, string $message, ?int $store_id, ?string $link): void
{
$groupsModel = new Groups();
$groups = $groupsModel->getGroupsWithPermission($permission);
foreach ($groups as $group) {
$this->createNotification($message, $group['group_name'], $store_id, $link);
}
}
// Notifier tous les groupes ayant une permission donnée, pour TOUS les stores actifs
public function notifyGroupsByPermissionAllStores(string $permission, string $message, ?string $link): void
{
$storesModel = new Stores();
$allStores = $storesModel->getActiveStore();
if (!is_array($allStores) || empty($allStores)) return;
foreach ($allStores as $store) {
$this->notifyGroupsByPermission($permission, $message, (int)$store['id'], $link);
}
}
// Marquer toutes les notifications comme lues pour l'utilisateur connecté
public function markAllAsRead()
{

136
app/Controllers/OrderController.php

@ -421,7 +421,7 @@ class OrderController extends AdminController
for ($i = 0; $i < count($product_id); $i++) {
$singleProduct = $product->getProductData($product_id[$i]);
if ($singleProduct['product_sold'] == true) {
$notification->createNotification("Produit en rupture de stock", "Direction", $store_id, "products");
$notification->notifyGroupsByPermission('notifProduit', "Produit en rupture de stock", $store_id, "products");
}
}
}
@ -448,20 +448,20 @@ class OrderController extends AdminController
$data['page_title'] = $this->pageTitle;
$validation = \Config\Services::validation();
$products = $this->request->getPost('product[]');
$products = $this->request->getPost('product');
if ($products !== null && (count($products) !== count(array_unique($products)))) {
return redirect()->back()->withInput()->with('errors', ['product' => 'Chaque produit sélectionné doit être unique.']);
}
$validation->setRules([
'product[]' => 'required',
'product' => 'required',
'customer_type' => 'required',
'source' => 'required'
]);
$validationData = [
'product[]' => $this->request->getPost('product[]'),
'product' => $this->request->getPost('product'),
'customer_type' => $this->request->getPost('customer_type'),
'source' => $this->request->getPost('source')
];
@ -470,7 +470,7 @@ class OrderController extends AdminController
$Company = new Company();
$Products = new Products();
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
if (strtolower($this->request->getMethod()) === 'post' && $validation->run($validationData)) {
$session = session();
$users = $session->get('user');
@ -479,11 +479,11 @@ class OrderController extends AdminController
$bill_no = $this->generateSimpleSequentialBillNo($users['store_id']);
$document_type = $this->request->getPost('document_type') ?? 'facture';
$posts = $this->request->getPost('product[]');
$rates = $this->request->getPost('rate_value[]');
$amounts = $this->request->getPost('amount_value[]');
$puissances = $this->request->getPost('puissance[]');
$quantities = $this->request->getPost('qty[]'); // ✅ RÉCUPÉRER LES QUANTITÉS
$posts = $this->request->getPost('product');
$rates = $this->request->getPost('rate_value');
$amounts = $this->request->getPost('amount_value');
$puissances = $this->request->getPost('puissance');
$quantities = $this->request->getPost('qty'); // ✅ RÉCUPÉRER LES QUANTITÉS
$discount = (float)$this->request->getPost('discount') ?? 0;
$gross_amount = $this->calculGross($amounts);
@ -599,10 +599,36 @@ class OrderController extends AdminController
if (isset($product['sku'], $product['price'])) {
$product_lines[] = $product['sku'] . ':' . $product['price'];
}
$product_info_lines[] = "• " . ($product['name'] ?? '-') .
" | N° Série : " . ($product['sku'] ?? '-') .
" | N° Moteur : " . ($product['numero_de_moteur'] ?? '-') .
" | Châssis : " . ($product['chasis'] ?? '-');
$name = $product['name'] ?? '-';
$sku = $product['sku'] ?? '-';
$moteur = $product['numero_de_moteur'] ?? '-';
$chasis = $product['chasis'] ?? '-';
$puissance= $product['puissance'] ?? '-';
$image = $product['image'] ?? '';
$imgUrl = base_url('assets/images/product_image/' . $image);
$details = htmlspecialchars(json_encode([
'name' => $name,
'sku' => $sku,
'moteur' => $moteur,
'chasis' => $chasis,
'puissance' => $puissance,
'image' => $image ? $imgUrl : '',
], JSON_UNESCAPED_UNICODE), ENT_QUOTES);
$imgTag = $image
? "<img src='{$imgUrl}' style='width:50px;height:40px;object-fit:cover;border-radius:4px;margin-right:8px;vertical-align:middle;' alt='{$name}'>"
: "<span style='display:inline-block;width:50px;height:40px;background:#eee;border-radius:4px;margin-right:8px;vertical-align:middle;text-align:center;line-height:40px;font-size:10px;color:#999;'>No img</span>";
$product_info_lines[] =
"<div style='display:flex;align-items:center;padding:4px 0;'>" .
$imgTag .
"<div style='flex:1;'><strong>{$name}</strong><br><small>N\u00b0 S\u00e9rie : {$sku}</small></div>" .
"<button onclick='event.preventDefault();event.stopPropagation();showMotoDetails(this)' " .
"data-moto='{$details}' " .
"style='background:none;border:none;cursor:pointer;color:#3c8dbc;font-size:18px;padding:0 4px;' title='Voir d\u00e9tails'>" .
"<i class='fa fa-info-circle'></i></button>" .
"</div>";
}
$product_output = implode("\n", $product_lines);
@ -629,21 +655,15 @@ class OrderController extends AdminController
"Demandeur : {$users['firstname']} {$users['lastname']}<br>" .
implode("<br>", $product_info_lines);
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification($message, "SuperAdmin", (int)$store['id'], 'remise/');
$Notification->createNotification($message . "<br><em>Pour information</em>", "Direction", (int)$store['id'], 'remise/');
$Notification->createNotification($message . "<br><em>Pour information</em>", "DAF", (int)$store['id'], 'remise/');
}
}
$Notification->notifyGroupsByPermissionAllStores('notifRemise', $message, 'remise/');
} else {
// Commande sans remise
$Notification->createNotification(
$Notification->notifyGroupsByPermission(
'notifSortieCaisse',
"📦 Nouvelle commande à valider : {$bill_no}<br>" .
"Client : {$data['customer_name']}<br>" .
"Montant : " . number_format($gross_amount, 0, ',', ' ') . " Ar",
"Caissière",
(int)$users['store_id'],
"orders"
);
@ -744,31 +764,8 @@ public function markAsDelivered()
"Livrée par : {$users['firstname']} {$users['lastname']}<br>" .
"Date livraison : " . date('d/m/Y H:i');
// ✅ NOTIFIER DIRECTION, DAF, SUPERADMIN DE TOUS LES STORES
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$messageGlobal,
"Direction",
(int)$store['id'],
'orders'
);
$Notification->createNotification(
$messageGlobal,
"DAF",
(int)$store['id'],
'orders'
);
$Notification->createNotification(
$messageGlobal,
"SuperAdmin",
(int)$store['id'],
'orders'
);
}
}
// ✅ NOTIFIER TOUS LES GROUPES AYANT validateCommande1
$Notification->notifyGroupsByPermissionAllStores('notifCommande', $messageGlobal, 'orders');
} catch (\Exception $e) {
// Si la notification échoue, on continue quand même
log_message('error', 'Erreur notification: ' . $e->getMessage());
@ -903,7 +900,7 @@ public function update(int $id)
$user = $session->get('user');
$role = $user['group_name'] ?? null;
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
if (strtolower($this->request->getMethod()) === 'post' && $validation->run($validationData)) {
$current_order_check = $Orders->getOrdersData($id);
if (in_array($current_order_check['paid_status'], [1, 3])) {
@ -1030,10 +1027,10 @@ public function update(int $id)
$customer_name = $this->request->getPost('customer_name');
$bill_no = $current_order['bill_no'];
// ✅ Notification SECURITE du store concerné
$Notification->createNotification(
// ✅ Notification groupes ayant createSecurite
$Notification->notifyGroupsByPermission(
'notifSecurite',
"Commande validée: {$bill_no} - Client: {$customer_name}",
"SECURITE",
(int)$user['store_id'],
'orders'
);
@ -1047,31 +1044,8 @@ public function update(int $id)
"Client : {$customer_name}<br>" .
"Validée par : {$user['firstname']} {$user['lastname']}";
// ✅ NOTIFIER DIRECTION, DAF, SUPERADMIN DE TOUS LES STORES
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$messageGlobal,
"Direction",
(int)$store['id'],
'orders'
);
$Notification->createNotification(
$messageGlobal,
"DAF",
(int)$store['id'],
'orders'
);
$Notification->createNotification(
$messageGlobal,
"SuperAdmin",
(int)$store['id'],
'orders'
);
}
}
// ✅ NOTIFIER TOUS LES GROUPES AYANT validateCommande1
$Notification->notifyGroupsByPermissionAllStores('notifCommande', $messageGlobal, 'orders');
}
if ((float)$discount > 0) {
@ -1113,13 +1087,7 @@ public function update(int $id)
"Store : " . $this->returnStore($user['store_id']) . "<br>" .
"Demandeur : {$user['firstname']} {$user['lastname']}";
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification($message, "SuperAdmin", (int)$store['id'], 'remise/');
$Notification->createNotification($message . "<br><em>Pour information</em>", "Direction", (int)$store['id'], 'remise/');
$Notification->createNotification($message . "<br><em>Pour information</em>", "DAF", (int)$store['id'], 'remise/');
}
}
$Notification->notifyGroupsByPermissionAllStores('notifRemise', $message, 'remise/');
}
session()->setFlashData('success', 'Commande mise à jour avec succès.');

11
app/Controllers/ProductCOntroller.php

@ -185,7 +185,7 @@ class ProductCOntroller extends AdminController
'price_min' => 'required|numeric',
]);
if ($this->request->getMethod() === 'post' && $validation->withRequest($this->request)->run()) {
if (strtolower($this->request->getMethod()) === 'post' && $validation->withRequest($this->request)->run()) {
$prix_min = (float)$this->request->getPost('price_min');
$prix_vente = (float)$this->request->getPost('price_vente');
@ -243,12 +243,7 @@ class ProductCOntroller extends AdminController
]);
session()->setFlashdata('success', 'Créé avec succès');
$Notification->createNotification(
"Un nouveau Produit a été créé",
"COMMERCIALE",
$store_id1,
'products/'
);
$Notification->notifyGroupsByPermission('notifProduit', "Un nouveau Produit a été créé", $store_id1, 'products/');
return redirect()->to('/products');
} else {
@ -321,7 +316,7 @@ class ProductCOntroller extends AdminController
$prix_minimal_data = $FourchettePrix->where('product_id', $id)->first();
$prix_minimal = $prix_minimal_data['prix_minimal'] ?? '';
if ($this->request->getMethod() === 'post' && $validation->withRequest($this->request)->run()) {
if (strtolower($this->request->getMethod()) === 'post' && $validation->withRequest($this->request)->run()) {
$availabilityValue = (int)$this->request->getPost('availability');
$availability = ($availabilityValue === 1) ? 1 : 0;

86
app/Controllers/RecouvrementController.php

@ -221,31 +221,8 @@ class RecouvrementController extends AdminController
"Montant: " . number_format($recouvrementData['recouvrement_montant'], 0, ',', ' ') . " Ar<br>" .
"Par: " . $users['firstname'] . ' ' . $users['lastname'];
// ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$message,
"Direction",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"DAF",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"SuperAdmin",
(int)$store['id'],
'recouvrement'
);
}
}
// ✅ Notifier tous les groupes ayant updateRecouvrement de TOUS les stores
$Notification->notifyGroupsByPermissionAllStores('notifRecouvrement', $message, 'recouvrement');
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification removeRecouvrement: ' . $e->getMessage());
@ -333,34 +310,8 @@ class RecouvrementController extends AdminController
"Store: " . $this->returnStoreName($users['store_id']) . "<br>" .
"Par: " . $fullname;
// ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
// Notifier Direction
$Notification->createNotification(
$message,
"Direction",
(int)$store['id'],
'recouvrement'
);
// Notifier DAF
$Notification->createNotification(
$message,
"DAF",
(int)$store['id'],
'recouvrement'
);
// Notifier SuperAdmin
$Notification->createNotification(
$message,
"SuperAdmin",
(int)$store['id'],
'recouvrement'
);
}
}
// ✅ Notifier tous les groupes ayant updateRecouvrement de TOUS les stores
$Notification->notifyGroupsByPermissionAllStores('notifRecouvrement', $message, 'recouvrement');
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification createRecouvrement: ' . $e->getMessage());
@ -405,7 +356,7 @@ class RecouvrementController extends AdminController
$Recouvrement = new Recouvrement();
if ($this->request->getMethod() === 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
$data = [
'recouvrement_montant' => (int) $this->request->getPost('recouvrement_montant_edit'),
'recouvrement_date' => $this->request->getPost('recouvrement_date_edit')
@ -426,31 +377,8 @@ class RecouvrementController extends AdminController
"Nouveau montant: " . number_format($data['recouvrement_montant'], 0, ',', ' ') . " Ar<br>" .
"Par: " . $users['firstname'] . ' ' . $users['lastname'];
// ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$message,
"Direction",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"DAF",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"SuperAdmin",
(int)$store['id'],
'recouvrement'
);
}
}
// ✅ Notifier tous les groupes ayant updateRecouvrement de TOUS les stores
$Notification->notifyGroupsByPermissionAllStores('notifRecouvrement', $message, 'recouvrement');
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification updateRecouvrement: ' . $e->getMessage());

110
app/Controllers/RemiseController.php

@ -19,7 +19,10 @@ class RemiseController extends AdminController
public function index()
{
$this->verifyRole('viewRemise');
if (!in_array('viewRemise', $this->permission) && !in_array('validateRemise', $this->permission)) {
redirect()->to('/')->send();
exit();
}
$data = json_decode($this->fetchTotal(),true);
@ -58,8 +61,8 @@ class RemiseController extends AdminController
foreach ($data as $key => $value) {
$buttons = '';
// ✅ SEUL LE SUPERADMIN PEUT VALIDER/REFUSER
if ($role === 'SuperAdmin' && $value['demande_status'] == 'En attente') {
// ✅ TOUS LES GROUPES AYANT validateRemise PEUVENT VALIDER/REFUSER
if (in_array('validateRemise', $this->permission) && $value['demande_status'] == 'En attente') {
$buttons .= '<button type="submit" class="btn btn-success" onclick="valideFunc(' . $value['id_demande'] . ')">';
$buttons .= '<i class="fa fa-check-circle"></i>';
$buttons .= '</button>';
@ -69,11 +72,6 @@ class RemiseController extends AdminController
$buttons .= '</button>';
}
// ✅ DIRECTION ET DAF VOIENT SEULEMENT (pas de boutons d'action)
if (in_array($role, ['Direction', 'DAF'])) {
$buttons = '<span class="label label-info">Consultation uniquement</span>';
}
$result['data'][$key] = [
$value['id_demande'],
$value['product'],
@ -92,19 +90,10 @@ class RemiseController extends AdminController
*/
public function updateRemise($id_demande)
{
// ✅ VÉRIFIER QUE SEUL LE SUPERADMIN PEUT VALIDER
$this->verifyRole('validateRemise');
$session = session();
$user = $session->get('user');
$role = $user['group_name'] ?? '';
if ($role !== 'SuperAdmin') {
return $this->response->setJSON([
'success' => false,
'messages' => 'Seul le SuperAdmin peut valider ou refuser les demandes de remise.'
]);
}
$this->verifyRole('validateRemise');
$validation = \Config\Services::validation();
$data['page_title'] = $this->pageTitle;
@ -119,7 +108,7 @@ class RemiseController extends AdminController
$Remise = new Remise();
if ($this->request->getMethod() == 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
$today = date('Y-m-d');
$demande_status = $this->request->getPost('demande_status');
@ -165,34 +154,13 @@ class RemiseController extends AdminController
// Message de refus
$messageRefus = "❌ Demande de remise refusée : {$bill_no}<br>" .
"Produit : {$remise_product}<br>" .
"Décision : SuperAdmin";
// Notifier le commercial du store concerné
$Notification->createNotification(
$messageRefus . "<br><em>Veuillez modifier la commande.</em>",
"COMMERCIALE",
(int)$store_id,
"orders"
);
// ✅ NOTIFIER DIRECTION ET DAF DE TOUS LES STORES (POUR INFORMATION)
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$messageRefus . "<br><em>Pour information</em>",
"Direction",
(int)$store['id'],
'remise/'
);
$Notification->createNotification(
$messageRefus . "<br><em>Pour information</em>",
"DAF",
(int)$store['id'],
'remise/'
);
}
}
"Décision : {$user['firstname']} {$user['lastname']} ({$user['group_name']})";
// Notifier les commerciaux du store concerné
$Notification->notifyGroupsByPermission('notifRemise', $messageRefus . "<br><em>Veuillez modifier la commande.</em>", (int)$store_id, "orders");
// ✅ NOTIFIER TOUS LES GROUPES AYANT validateRemise (POUR INFORMATION)
$Notification->notifyGroupsByPermissionAllStores('notifRemise', $messageRefus . "<br><em>Pour information</em>", 'remise/');
$message = 'La demande de remise a été refusée. Le commercial et les responsables ont été notifiés.';
@ -204,42 +172,16 @@ class RemiseController extends AdminController
$messageAcceptation = "✅ Demande de remise acceptée : {$bill_no}<br>" .
"Produit : {$remise_product}<br>" .
"Décision : SuperAdmin";
// Notifier la Caissière du store concerné
$Notification->createNotification(
$messageAcceptation . "<br><em>Commande prête à être traitée</em>",
"Caissière",
(int)$store_id,
"orders"
);
// Notifier le commercial du store concerné
$Notification->createNotification(
$messageAcceptation,
"COMMERCIALE",
(int)$store_id,
"orders"
);
// ✅ NOTIFIER DIRECTION ET DAF DE TOUS LES STORES (POUR INFORMATION)
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$messageAcceptation . "<br><em>Pour information</em>",
"Direction",
(int)$store['id'],
'remise/'
);
$Notification->createNotification(
$messageAcceptation . "<br><em>Pour information</em>",
"DAF",
(int)$store['id'],
'remise/'
);
}
}
"Décision : {$user['firstname']} {$user['lastname']} ({$user['group_name']})";
// Notifier les caissières du store concerné
$Notification->notifyGroupsByPermission('notifSortieCaisse', $messageAcceptation . "<br><em>Commande prête à être traitée</em>", (int)$store_id, "orders");
// Notifier les commerciaux du store concerné
$Notification->notifyGroupsByPermission('notifRemise', $messageAcceptation, (int)$store_id, "orders");
// ✅ NOTIFIER TOUS LES GROUPES AYANT validateRemise (POUR INFORMATION)
$Notification->notifyGroupsByPermissionAllStores('notifRemise', $messageAcceptation . "<br><em>Pour information</em>", 'remise/');
$message = 'La demande de remise a été acceptée. La caissière, le commercial et les responsables ont été notifiés.';
}

2
app/Controllers/SecuriteController.php

@ -116,7 +116,7 @@ class SecuriteController extends AdminController
$Notification = new NotificationController();
if ($storeModel->updateSecurite($data, $id)) {
if ($post['status'] === "Validé") {
$Notification->createNotification('Une commande a été validé', "COMMERCIALE",(int)$users['store_id'], 'orders');
$Notification->notifyGroupsByPermission('notifRemise', 'Une commande a été validé', (int)$users['store_id'], 'orders');
}
$response = ['success' => true, 'messages' => 'Mise à jour réussie'];
} else {

32
app/Controllers/SortieCaisseController.php

@ -574,16 +574,7 @@ public function markAsPaid($id_sortie)
"Store: " . $this->returnStoreName($decaissement['store_id']) . "<br>" .
"Nouveau solde " . $mode_paiement_label . ": " . number_format($fonds_disponible - $montant_retire, 0, ',', ' ') . " Ar";
$Stores = new Stores();
$allStores = $Stores->getActiveStore();
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification($message, "Direction", (int)$store['id'], 'sortieCaisse');
$Notification->createNotification($message, "DAF", (int)$store['id'], 'sortieCaisse');
$Notification->createNotification($message, "SuperAdmin", (int)$store['id'], 'sortieCaisse');
}
}
$Notification->notifyGroupsByPermissionAllStores('notifSortieCaisse', $message, 'sortieCaisse');
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification markAsPaid: ' . $e->getMessage());
@ -856,16 +847,7 @@ public function markAsPaid($id_sortie)
"Store: " . $this->returnStoreName($user['store_id']) . "<br>" .
"Demandeur: " . $user['firstname'] . ' ' . $user['lastname'];
$Stores = new Stores();
$allStores = $Stores->getActiveStore();
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification($message, "Direction", (int)$store['id'], 'sortieCaisse');
$Notification->createNotification($message, "DAF", (int)$store['id'], 'sortieCaisse');
$Notification->createNotification($message, "SuperAdmin", (int)$store['id'], 'sortieCaisse');
}
}
$Notification->notifyGroupsByPermissionAllStores('notifSortieCaisse', $message, 'sortieCaisse');
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification createSortieCaisse: ' . $e->getMessage());
@ -899,7 +881,7 @@ public function markAsPaid($id_sortie)
$data['page_title'] = $this->pageTitle;
if ($this->request->getMethod() === 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
$validation = \Config\Services::validation();
$validation->setRules([
@ -1032,7 +1014,7 @@ public function markAsPaid($id_sortie)
$data['page_title'] = $this->pageTitle;
if ($this->request->getMethod() === 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
$data = [
'admin_raison' => $this->request->getPost('admin_raison'),
'statut' => $this->request->getPost('statut'),
@ -1054,15 +1036,15 @@ public function markAsPaid($id_sortie)
switch ($statut) {
case "Valider":
$message = "✅ Le décaissement a été validé par la Direction<br>Store: " . $this->returnStoreName($store_id);
$Notification->createNotification($message, "Caissière", (int)$store_id, 'sortieCaisse');
$Notification->notifyGroupsByPermission('notifSortieCaisse', $message, (int)$store_id, 'sortieCaisse');
break;
case "Refuser":
$message = "❌ Le décaissement a été refusé par la Direction<br>Store: " . $this->returnStoreName($store_id) . "<br>Raison: " . $this->request->getPost('admin_raison');
$Notification->createNotification($message, "Caissière", (int)$store_id, 'sortieCaisse');
$Notification->notifyGroupsByPermission('notifSortieCaisse', $message, (int)$store_id, 'sortieCaisse');
break;
case "En attente":
$message = "⏳ Le décaissement a été mis en attente par la Direction<br>Store: " . $this->returnStoreName($store_id);
$Notification->createNotification($message, "Caissière", (int)$store_id, 'sortieCaisse');
$Notification->notifyGroupsByPermission('notifSortieCaisse', $message, (int)$store_id, 'sortieCaisse');
break;
}

6
app/Controllers/UserController.php

@ -209,7 +209,7 @@ class UserController extends AdminController
$data['page_title'] = $this->pageTitle;
// Check if it's a POST request before validating
if ($this->request->getMethod() === 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
// Load validation service and run validation
if (!$this->validate($validationRules)) {
@ -285,7 +285,7 @@ class UserController extends AdminController
// Check if the ID exists in the request
if ($id) {
// Check if it's a POST request before validating
if ($this->request->getMethod() === 'post') {
if (strtolower($this->request->getMethod()) === 'post') {
// Validate the form
if (!$this->validate($validationRules)) {
// Validation failed
@ -405,7 +405,7 @@ class UserController extends AdminController
]);
$Users = new Users();
// If validation passes for the first set of rules
if ($this->request->getMethod() === 'post' && $validation->withRequest($this->request)->run()) {
if (strtolower($this->request->getMethod()) === 'post' && $validation->withRequest($this->request)->run()) {
// Handle the case when password is not being updated
if (empty($this->request->getPost('password')) && empty($this->request->getPost('cpassword'))) {

18
app/Models/Groups.php

@ -99,4 +99,22 @@ class Groups extends Model
->get()
->getRowArray();
}
/**
* Get all groups that have a specific permission
* @param string $permission
* @return array
*/
public function getGroupsWithPermission(string $permission): array
{
$groups = $this->findAll();
$result = [];
foreach ($groups as $group) {
$perms = @unserialize($group['permission'] ?? '');
if (is_array($perms) && in_array($permission, $perms)) {
$result[] = $group;
}
}
return $result;
}
}

73
app/Views/groups/edit.php

@ -75,6 +75,7 @@
<th>Voir</th>
<th>Supprimer</th>
<th>Assigner</th>
<th>Notification</th>
</tr>
</thead>
<tbody>
@ -96,6 +97,7 @@
</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Utilisateurs</td>
@ -140,6 +142,7 @@
}
}
?>></td>
<td>-</td>
</tr>
<tr>
<td>Rôle</td>
@ -176,6 +179,7 @@
}
?>></td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Marques</td>
@ -204,6 +208,7 @@
}
} ?>></td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Categories</td>
@ -236,6 +241,7 @@
}
} ?>></td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Point de ventes</td>
@ -269,6 +275,7 @@
echo "checked";
}
} ?>></td>
<td>-</td>
</tr>
<td>Mécanicien</td>
@ -305,6 +312,7 @@
} ?>>
</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Attributs</td>
@ -337,6 +345,7 @@
}
} ?>></td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Produits</td>
@ -368,6 +377,12 @@
}
} ?>></td>
<td>-</td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifProduit"
<?php if ($serialize_permission) {
if (in_array('notifProduit', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
<td>Commandes</td>
@ -396,6 +411,12 @@
}
} ?>></td>
<td>-</td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifCommande"
<?php if ($serialize_permission) {
if (in_array('notifCommande', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
<td>Recouvrement</td>
@ -424,6 +445,12 @@
}
} ?>></td>
<td>-</td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifRecouvrement"
<?php if ($serialize_permission) {
if (in_array('notifRecouvrement', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
@ -458,6 +485,12 @@
echo "checked";
}
} ?>></td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifSortieCaisse"
<?php if ($serialize_permission) {
if (in_array('notifSortieCaisse', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
<td>Autres encaissements</td>
@ -484,7 +517,14 @@
if (in_array('deleteEncaissement', $serialize_permission)) {
echo "checked";
}
} ?>>
} ?>></td>
<td>-</td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifEncaissement"
<?php if ($serialize_permission) {
if (in_array('notifEncaissement', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
<td>Remise</td>
@ -506,6 +546,14 @@
echo "checked";
}
} ?>></td>
<td>-</td>
<td>-</td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifRemise"
<?php if ($serialize_permission) {
if (in_array('notifRemise', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
<td>Validation Commande</td>
@ -527,7 +575,9 @@
echo "checked";
}
} ?>></td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Sécurité</td>
@ -557,6 +607,13 @@
echo "checked";
}
} ?>> </td>
<td>-</td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifSecurite"
<?php if ($serialize_permission) {
if (in_array('notifSecurite', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
@ -587,6 +644,13 @@
echo "checked";
}
} ?>> </td>
<td>-</td>
<td><input type="checkbox" name="permission[]" id="permission" class="minimal" value="notifAvance"
<?php if ($serialize_permission) {
if (in_array('notifAvance', $serialize_permission)) {
echo "checked";
}
} ?>></td>
</tr>
<tr>
@ -601,6 +665,7 @@
} ?>></td>
<td> - </td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Entreprise</td>
@ -615,6 +680,7 @@
<td> - </td>
<td> - </td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Profile</td>
@ -628,6 +694,7 @@
} ?>></td>
<td> - </td>
<td>-</td>
<td>-</td>
</tr>
<tr>
@ -642,6 +709,7 @@
} ?>></td>
<td> - </td>
<td>-</td>
<td>-</td>
</tr>
<tr>
@ -657,6 +725,7 @@
<td> - </td>
<td> - </td>
<td>-</td>
<td>-</td>
</tr>
</tbody>
</table>

33
app/Views/orders/create.php

@ -52,14 +52,6 @@
</div>
<!-- /.box-header -->
<form role="form" action="<?php base_url('orders/create') ?>" method="post" class="form-horizontal">
<?php if (isset($validation) && $validation->getErrors()): ?>
<div class="alert alert-danger">
<ul>
<?= $validation->listErrors() ?>
</ul>
</div>
<?php endif; ?>
<div class="box-body">
@ -108,6 +100,31 @@
placeholder="Entrer ne CIN du client" autocomplete="off" required value="<?= old('customer_cin') ?>">
</div>
</div>
<div class="form-group">
<label for="customer_type" class="col-sm-5 control-label" style="text-align:left;">Type de client <span class="text-danger">*</span></label>
<div class="col-sm-7">
<select class="form-control" id="customer_type" name="customer_type" required>
<option value="">-- Sélectionner --</option>
<option value="particulier" <?= old('customer_type') == 'particulier' ? 'selected' : '' ?>>Particulier</option>
<option value="revendeur" <?= old('customer_type') == 'revendeur' ? 'selected' : '' ?>>Revendeur</option>
</select>
</div>
</div>
<div class="form-group">
<label for="source" class="col-sm-5 control-label" style="text-align:left;">Source <span class="text-danger">*</span></label>
<div class="col-sm-7">
<select class="form-control" id="source" name="source" required>
<option value="">-- Sélectionner --</option>
<option value="facebook_perso" <?= old('source') == 'facebook_perso' ? 'selected' : '' ?>>Facebook perso</option>
<option value="page_motorbike" <?= old('source') == 'page_motorbike' ? 'selected' : '' ?>>Page motorbike</option>
<option value="bouche_a_oreille" <?= old('source') == 'bouche_a_oreille' ? 'selected' : '' ?>>Bouche à oreille</option>
<option value="commercial_interne" <?= old('source') == 'commercial_interne' ? 'selected' : '' ?>>Commercial interne</option>
<option value="autre" <?= old('source') == 'autre' ? 'selected' : '' ?>>Autre</option>
</select>
</div>
</div>
</div>

65
app/Views/templates/header_menu.php

@ -16,10 +16,10 @@
<ul class="navbar-nav" style="position: absolute; right: 15px; top: 50%; transform: translateY(-50%); margin: 0; padding: 0; list-style: none; display: flex; align-items: center; gap: 20px;">
<!-- Notifications -->
<li class="nav-item dropdown" style="position: relative;">
<i class="fa fa-bell" id="notificationIcon" style="font-size: 20px; cursor: pointer; color:white;" data-toggle="dropdown"></i>
<li class="nav-item" style="position: relative;">
<i class="fa fa-bell" id="notificationIcon" style="font-size: 20px; cursor: pointer; color:white;" onclick="toggleNotifPanel()"></i>
<span id="notificationCount" class="navbar-badge"></span>
<div class="dropdown-menu dropdown-menu-right notif-dropdown">
<div id="notifPanel" class="notif-dropdown" style="display:none; position:absolute; right:0; top:35px; z-index:9999;">
<div class="notif-panel-header">
<span class="notif-panel-title" id="notificationHeader">
<i class="fa fa-bell"></i> Notifications
@ -126,6 +126,7 @@
#notificationList {
overflow-y: auto;
flex: 1;
max-height: 460px;
padding: 8px;
background: #f8f9fa;
}
@ -234,6 +235,21 @@
</style>
<script>
function toggleNotifPanel() {
var panel = document.getElementById('notifPanel');
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
}
// Fermer le panel en cliquant en dehors
document.addEventListener('click', function(e) {
var panel = document.getElementById('notifPanel');
var icon = document.getElementById('notificationIcon');
var badge = document.getElementById('notificationCount');
if (panel.style.display === 'block' && !panel.contains(e.target) && e.target !== icon && e.target !== badge) {
panel.style.display = 'none';
}
});
function fetchNotifications() {
$.ajax({
url: '/notifications',
@ -359,4 +375,47 @@ $(document).on('click', '#markAllAsReadBtn', function(e) {
setInterval(fetchNotifications, 10000);
fetchNotifications();
function showMotoDetails(btn) {
var data = JSON.parse(btn.getAttribute('data-moto'));
document.getElementById('motoModalName').textContent = data.name || '-';
document.getElementById('motoModalSku').textContent = data.sku || '-';
document.getElementById('motoModalMoteur').textContent = data.moteur || '-';
document.getElementById('motoModalChasis').textContent = data.chasis || '-';
document.getElementById('motoModalPuissance').textContent= data.puissance || '-';
var imgEl = document.getElementById('motoModalImg');
if (data.image) {
imgEl.src = data.image;
imgEl.style.display = 'block';
} else {
imgEl.style.display = 'none';
}
$('#motoDetailModal').modal('show');
}
</script>
<!-- Modal détails moto -->
<div class="modal fade" id="motoDetailModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header" style="background:#3c8dbc;color:#fff;">
<button type="button" class="close" data-dismiss="modal" style="color:#fff;opacity:1;">&times;</button>
<h4 class="modal-title"><i class="fa fa-motorcycle"></i> Détails de la moto</h4>
</div>
<div class="modal-body" style="text-align:center;">
<img id="motoModalImg" src="" alt="Photo moto"
style="max-width:100%;max-height:250px;object-fit:contain;border-radius:8px;margin-bottom:16px;border:1px solid #eee;">
<table class="table table-bordered table-condensed" style="text-align:left;margin-top:10px;">
<tr><th style="width:40%">Modèle</th><td id="motoModalName"></td></tr>
<tr><th>N° Série</th><td id="motoModalSku"></td></tr>
<tr><th>N° Moteur</th><td id="motoModalMoteur"></td></tr>
<tr><th>Châssis</th><td id="motoModalChasis"></td></tr>
<tr><th>Puissance</th><td id="motoModalPuissance"></td></tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
Loading…
Cancel
Save