feat: modifications et corrections du 03-04-2026

- Bouton impression conditionnel : 2 boutons (Facture + BL) si 1 produit, 1 bouton (BL) si plusieurs produits
- Ajout filtres (date, point de vente, utilisateur) sur la page Rapports principale
- Ajout filtres (date, point de vente) sur la page Rapports/Stock pour les 3 tableaux
- Remplacement affichage "UGS" par "N° SERIE" dans toutes les pages
- Mise en page facture avec remise : titre FACTURE repositionné, tableau plus compact
- Correction remise commandes multi-produits : total_price recevait un tableau au lieu d'un nombre
- SuperAdmin voit toutes les remises (tous statuts) au lieu de seulement "En attente"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
andrymodeste 2026-04-04 08:49:40 +02:00
parent fe80b9c4f8
commit 38d37a0987
10 changed files with 402 additions and 264 deletions

View File

@ -103,6 +103,15 @@ class OrderController extends AdminController
$buttons = ''; $buttons = '';
$discount = (float)$value['discount']; $discount = (float)$value['discount'];
$itemCount = (int)$value['item_count'];
// Génération des boutons d'impression
if ($itemCount > 1) {
$printButtons = '<a target="_blank" href="' . site_url('orders/printDivBL/' . $value['id']) . '" class="btn btn-default" title="Bon de livraison"><i class="fa fa-print"></i></a>';
} else {
$printButtons = '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default" title="Facture"><i class="fa fa-print"></i></a>';
$printButtons .= ' <a target="_blank" href="' . site_url('orders/printDivBL/' . $value['id']) . '" class="btn btn-info" title="Bon de livraison"><i class="fa fa-file-text-o"></i></a>';
}
// ✅ VÉRIFICATION : Si la commande est refusée (paid_status = 0), aucun bouton // ✅ VÉRIFICATION : Si la commande est refusée (paid_status = 0), aucun bouton
if ($value['paid_status'] == 0) { if ($value['paid_status'] == 0) {
@ -112,15 +121,15 @@ class OrderController extends AdminController
if (in_array('viewOrder', $this->permission)) { if (in_array('viewOrder', $this->permission)) {
// CAS 1 : Commande payée (1) ou livrée (3) → Toujours afficher imprimer // CAS 1 : Commande payée (1) ou livrée (3) → Toujours afficher imprimer
if (in_array($value['paid_status'], [1, 3])) { if (in_array($value['paid_status'], [1, 3])) {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>'; $buttons .= $printButtons;
} }
// CAS 2 : Commande en attente (2) SANS remise → Afficher imprimer // CAS 2 : Commande en attente (2) SANS remise → Afficher imprimer
elseif ($value['paid_status'] == 2 && $discount == 0) { elseif ($value['paid_status'] == 2 && $discount == 0) {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>'; $buttons .= $printButtons;
} }
// CAS 3 : Commande en attente (2) AVEC remise validée → Afficher imprimer // CAS 3 : Commande en attente (2) AVEC remise validée → Afficher imprimer
elseif ($value['paid_status'] == 2 && $Remise->hasRemiseValidatedForOrder($value['id'])) { elseif ($value['paid_status'] == 2 && $Remise->hasRemiseValidatedForOrder($value['id'])) {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>'; $buttons .= $printButtons;
} }
// CAS 4 : Commande en attente (2) AVEC remise en attente → Indicateur // CAS 4 : Commande en attente (2) AVEC remise en attente → Indicateur
elseif ($value['paid_status'] == 2 && $Remise->hasRemisePendingForOrder($value['id'])) { elseif ($value['paid_status'] == 2 && $Remise->hasRemisePendingForOrder($value['id'])) {
@ -224,10 +233,16 @@ class OrderController extends AdminController
$date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); $date_time = date('d-m-Y h:i a', strtotime($value['date_time']));
$buttons = ''; $buttons = '';
$itemCount = (int)$value['item_count'];
// Bouton imprimer // Bouton imprimer
if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") { if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>'; if ($itemCount > 1) {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDivBL/' . $value['id']) . '" class="btn btn-default" title="Bon de livraison"><i class="fa fa-print"></i></a>';
} else {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default" title="Facture"><i class="fa fa-print"></i></a>';
$buttons .= ' <a target="_blank" href="' . site_url('orders/printDivBL/' . $value['id']) . '" class="btn btn-info" title="Bon de livraison"><i class="fa fa-file-text-o"></i></a>';
}
} }
// ✅ Bouton modifier pour statuts 0 (Refusé) et 2 (En Attente) // ✅ Bouton modifier pour statuts 0 (Refusé) et 2 (En Attente)
@ -290,10 +305,16 @@ class OrderController extends AdminController
$date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); $date_time = date('d-m-Y h:i a', strtotime($value['date_time']));
$buttons = ''; $buttons = '';
$itemCount = (int)$value['item_count'];
// Bouton imprimer // Bouton imprimer
if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") { if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>'; if ($itemCount > 1) {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDivBL/' . $value['id']) . '" class="btn btn-default" title="Bon de livraison"><i class="fa fa-print"></i></a>';
} else {
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default" title="Facture"><i class="fa fa-print"></i></a>';
$buttons .= ' <a target="_blank" href="' . site_url('orders/printDivBL/' . $value['id']) . '" class="btn btn-info" title="Bon de livraison"><i class="fa fa-file-text-o"></i></a>';
}
} }
// ✅ Bouton modifier pour statuts 0 et 2, ET si c'est l'utilisateur créateur // ✅ Bouton modifier pour statuts 0 et 2, ET si c'est l'utilisateur créateur
@ -642,7 +663,7 @@ class OrderController extends AdminController
$data1 = [ $data1 = [
'date_demande' => date('Y-m-d H:i:s'), 'date_demande' => date('Y-m-d H:i:s'),
'montant_demande' => $discount, 'montant_demande' => $discount,
'total_price' => $amounts, 'total_price' => $gross_amount,
'id_store' => $users['store_id'], 'id_store' => $users['store_id'],
'id_order' => $order_id, 'id_order' => $order_id,
'product' => $product_output, 'product' => $product_output,
@ -1112,7 +1133,7 @@ public function update(int $id)
$data1 = [ $data1 = [
'date_demande' => date('Y-m-d H:i:s'), 'date_demande' => date('Y-m-d H:i:s'),
'montant_demande' => $this->request->getPost('discount'), 'montant_demande' => $this->request->getPost('discount'),
'total_price' => $amounts, 'total_price' => $gross_amount,
'id_store' => $user['store_id'], 'id_store' => $user['store_id'],
'id_order' => $id, 'id_order' => $id,
'product' => $product_output, 'product' => $product_output,
@ -2080,6 +2101,7 @@ public function print5(int $id)
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-bottom: 2px dashed #aaa; border-bottom: 2px dashed #aaa;
overflow: hidden;
} }
.facture-box:last-child { .facture-box:last-child {
@ -2091,7 +2113,6 @@ public function print5(int $id)
font-size: 24px; font-size: 24px;
font-weight: bold; font-weight: bold;
text-decoration: underline; text-decoration: underline;
margin-bottom: 12px;
} }
.f-company { .f-company {
@ -2120,13 +2141,13 @@ public function print5(int $id)
.f-table { .f-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
margin-bottom: 10px; margin-bottom: 6px;
} }
.f-table th, .f-table td { .f-table th, .f-table td {
border-left: 2px solid #000; border-left: 2px solid #000;
border-right: 2px solid #000; border-right: 2px solid #000;
padding: 8px 10px; padding: 3px 8px;
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
} }
@ -2137,7 +2158,7 @@ public function print5(int $id)
border-bottom: 2px solid #000; border-bottom: 2px solid #000;
} }
.f-table td { height: 30px; } .f-table td { height: 20px; }
.f-table tbody tr:last-child td { .f-table tbody tr:last-child td {
border-bottom: 2px solid #000; border-bottom: 2px solid #000;
@ -2147,7 +2168,7 @@ public function print5(int $id)
.f-words { .f-words {
font-size: 12px; font-size: 12px;
line-height: 1.3; line-height: 1.3;
margin-bottom: 12px; margin-bottom: 8px;
} }
/* Signatures */ /* Signatures */
@ -2268,8 +2289,6 @@ public function print5(int $id)
$qrId = 'qr_recto_'.$i; $qrId = 'qr_recto_'.$i;
$html .= ' $html .= '
<div class="facture-box"> <div class="facture-box">
<div class="f-title" style="text-align:center;">FACTURE</div>
<div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:8px;"> <div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:8px;">
<div class="f-company" style="margin-bottom:0;"> <div class="f-company" style="margin-bottom:0;">
<strong>'.$companyName.'</strong><br> <strong>'.$companyName.'</strong><br>
@ -2278,6 +2297,9 @@ public function print5(int $id)
Contact : '.$companyPhone.' / '.$companyPhone2.'<br> Contact : '.$companyPhone.' / '.$companyPhone2.'<br>
'.$companyAddress.' '.$companyAddress.'
</div> </div>
<div style="text-align:center; flex:1;">
<div class="f-title">FACTURE</div>
</div>
<div style="text-align:right; font-size:12px;"> <div style="text-align:right; font-size:12px;">
<div>DATE : '.$today.'</div> <div>DATE : '.$today.'</div>
<div> : '.$billNo.'</div> <div> : '.$billNo.'</div>

View File

@ -32,13 +32,36 @@ class ReportController extends AdminController
$today_year = $this->request->getPost('select_year'); $today_year = $this->request->getPost('select_year');
} }
// Récupérer les filtres
$startDate = $this->request->getPost('start_date') ?: null;
$endDate = $this->request->getPost('end_date') ?: null;
$storeId = $this->request->getPost('store_id') ?: null;
$userId = $this->request->getPost('user_id') ?: null;
// Fetch order data and years // Fetch order data and years
$Reports = new Reports(); $Reports = new Reports();
$Orders = new Orders(); $Orders = new Orders();
$Store = new Stores(); $Store = new Stores();
$parking_data = $Reports->getOrderData($today_year); $parking_data = $Reports->getOrderData($today_year, $startDate, $endDate, $storeId, $userId);
$data['report_years'] = $Reports->getOrderYear(); $data['report_years'] = $Reports->getOrderYear();
// Charger les stores et users pour les filtres
$data['stores'] = $Store->getActiveStore();
$db = \Config\Database::connect();
$data['users_list'] = $db->table('users u')
->select('u.id, u.firstname, u.lastname, g.group_name')
->join('user_group ug', 'u.id = ug.user_id')
->join('groups g', 'ug.group_id = g.id')
->whereIn('g.group_name', ['COMMERCIALE', 'Caissière', "Cheffe d'Agence"])
->orderBy('u.firstname', 'ASC')
->get()->getResultArray();
// Conserver les filtres sélectionnés
$data['selected_start_date'] = $startDate;
$data['selected_end_date'] = $endDate;
$data['selected_store_id'] = $storeId;
$data['selected_user_id'] = $userId;
// Process the parking data and calculate total amounts // Process the parking data and calculate total amounts
$final_parking_data = []; $final_parking_data = [];
@ -47,7 +70,6 @@ class ReportController extends AdminController
if (!empty($orders)) { if (!empty($orders)) {
foreach ($orders as $order) { foreach ($orders as $order) {
// Utiliser le montant selon la logique : discount si existe, sinon gross_amount
if (!empty($order['discount']) && $order['discount'] > 0) { if (!empty($order['discount']) && $order['discount'] > 0) {
$total_amount_earned += (float) $order['discount']; $total_amount_earned += (float) $order['discount'];
} else { } else {
@ -58,18 +80,19 @@ class ReportController extends AdminController
$final_parking_data[$month] = $total_amount_earned; $final_parking_data[$month] = $total_amount_earned;
} }
// Data for the camembert (pie chart) // Data for the camembert (pie chart)
$paymentModes = $Orders->getPaymentModes(); $paymentModes = $Orders->getPaymentModes($startDate, $endDate, $storeId, $userId);
$total_mvola1 = $paymentModes->total_mvola1; $total_mvola1 = $paymentModes->total_mvola1 ?? 0;
$total_mvola2 = $paymentModes->total_mvola2; $total_mvola2 = $paymentModes->total_mvola2 ?? 0;
$total_espece1 = $paymentModes->total_espece1; $total_espece1 = $paymentModes->total_espece1 ?? 0;
$total_espece2 = $paymentModes->total_espece2; $total_espece2 = $paymentModes->total_espece2 ?? 0;
$total_banque1 = $paymentModes->total_virement_bancaire1; $total_banque1 = $paymentModes->total_virement_bancaire1 ?? 0;
$total_banque2 = $paymentModes->total_virement_bancaire2; $total_banque2 = $paymentModes->total_virement_bancaire2 ?? 0;
$total_mvola = $total_mvola1 + $total_mvola2; $total_mvola = $total_mvola1 + $total_mvola2;
$total_banque = $total_banque1 + $total_banque2; $total_banque = $total_banque1 + $total_banque2;
$total_espece = $total_espece1 + $total_espece2; $total_espece = $total_espece1 + $total_espece2;
$totalOrders = $Orders->getTotalOrders(); $totalOrders = $Orders->getTotalOrders($startDate, $endDate, $storeId, $userId);
$totalAmountPerPaymentModes = ["MVOLA" => $total_mvola, "Espece" => $total_espece, "Virement Bancaire" => $total_banque]; $totalAmountPerPaymentModes = ["MVOLA" => $total_mvola, "Espece" => $total_espece, "Virement Bancaire" => $total_banque];
$totalOrdersCount = (int) $totalOrders->total_orders; $totalOrdersCount = (int) $totalOrders->total_orders;
$labels = []; $labels = [];
@ -87,10 +110,10 @@ class ReportController extends AdminController
// Prepare data for product chart // Prepare data for product chart
$OrderItem = new OrderItems(); $OrderItem = new OrderItems();
$productTable = $OrderItem->getAllSoldProductToday(); $productTable = $OrderItem->getAllSoldProductToday($startDate, $endDate, $storeId, $userId);
$product_sold = (int) $productTable->total_product_sold; $product_sold = (int) ($productTable->total_product_sold ?? 0);
$unsold_product = (int) $productTable->total_unsold_product; $unsold_product = (int) ($productTable->total_unsold_product ?? 0);
$labels1 = ["Produits vendus", "Produits non vendus"]; $labels1 = ["Produits vendus", "Produits non vendus"];
$totals2 = [$product_sold, $unsold_product]; $totals2 = [$product_sold, $unsold_product];
@ -104,8 +127,8 @@ class ReportController extends AdminController
$data['results'] = $final_parking_data; $data['results'] = $final_parking_data;
// Data for the camembert in dashboard // Data for the camembert in dashboard
$totalStoreOrder = $Orders->getTotalOrderPerStore(); $totalStoreOrder = $Orders->getTotalOrderPerStore($startDate, $endDate, $storeId, $userId);
$totalOrders = $Orders->getTotalOrders(); $totalOrders = $Orders->getTotalOrders($startDate, $endDate, $storeId, $userId);
$totalOrdersCount = (int) $totalOrders->total_orders; $totalOrdersCount = (int) $totalOrders->total_orders;
// Initialisation des variables pour éviter l'erreur "Undefined variable" // Initialisation des variables pour éviter l'erreur "Undefined variable"
@ -115,7 +138,7 @@ class ReportController extends AdminController
foreach ($totalStoreOrder as $totalOrdersInStore) { foreach ($totalStoreOrder as $totalOrdersInStore) {
$storeList = $Store->getStoreById($totalOrdersInStore->store_id); $storeList = $Store->getStoreById($totalOrdersInStore->store_id);
$labelStore[] = $storeList->name ?? 'Inconnu'; $labelStore[] = $storeList->name ?? 'Inconnu';
$totalPerStore[] = ((int) $totalOrdersInStore->total / $totalOrdersCount) * 100; $totalPerStore[] = ($totalOrdersCount > 0) ? ((int) $totalOrdersInStore->total / $totalOrdersCount) * 100 : 0;
} }
$data['labelStore'] = json_encode($labelStore); $data['labelStore'] = json_encode($labelStore);
@ -169,13 +192,13 @@ class ReportController extends AdminController
{ {
$Orders = new Orders(); $Orders = new Orders();
$productVente = $Orders->getTotalProductvente2($id); $startDate = $this->request->getGet('startDate');
$endDate = $this->request->getGet('endDate');
$productVente = $Orders->getTotalProductvente2($id, $startDate, $endDate);
$result = ['data' => []]; $result = ['data' => []];
foreach ($productVente as $key => $value) { foreach ($productVente as $key => $value) {
// die(var_dump($value)); // Debugging: Check what $value contains
// Add the row data
$result['data'][$key] = [ $result['data'][$key] = [
$value->sku, $value->sku,
$value->date_time, $value->date_time,
@ -183,7 +206,6 @@ class ReportController extends AdminController
]; ];
} }
// Return data in JSON format
return $this->response->setJSON($result); return $this->response->setJSON($result);
} }
@ -223,15 +245,13 @@ class ReportController extends AdminController
{ {
$Products = new Orders(); $Products = new Orders();
$produitStock = $Products->getOrderVendue(); $startDate = $this->request->getGet('startDate');
$endDate = $this->request->getGet('endDate');
$produitStock = $Products->getOrderVendue($id, $startDate, $endDate);
$result = ['data' => []]; $result = ['data' => []];
// echo '<pre>';
// die(var_dump($produitStock));
foreach ($produitStock as $key => $value) { foreach ($produitStock as $key => $value) {
// die(var_dump($value)); // Debugging: Check what $value contains
// Add the row data
$result['data'][$key] = [ $result['data'][$key] = [
$value['sku'], $value['sku'],
$value['qty'], $value['qty'],
@ -241,7 +261,6 @@ class ReportController extends AdminController
]; ];
} }
// Return data in JSON format
return $this->response->setJSON($result); return $this->response->setJSON($result);
} }
@ -526,7 +545,7 @@ class ReportController extends AdminController
$imageUrl, // 0 - Image $imageUrl, // 0 - Image
$order['bill_no'] ?? 'N/A', // 1 - N° Facture $order['bill_no'] ?? 'N/A', // 1 - N° Facture
$product['name'], // 2 - Désignation $product['name'], // 2 - Désignation
$product['sku'], // 3 - UGS $product['sku'], // 3 - N° SERIE
$brandName, // 4 - Marque $brandName, // 4 - Marque
$order['customer_name'], // 5 - Client $order['customer_name'], // 5 - Client
$agentName, // 6 - Agent Sécurité $agentName, // 6 - Agent Sécurité

View File

@ -61,7 +61,7 @@ class SecuriteController extends AdminController
$result['data'][] = [ $result['data'][] = [
'image' => $img, 'image' => $img,
'ugs' => esc($product['sku']), 'num_serie' => esc($product['sku']),
'designation' => esc($product['name']), 'designation' => esc($product['name']),
'statut' => $statut, 'statut' => $statut,
'action' => $buttons 'action' => $buttons
@ -88,7 +88,7 @@ class SecuriteController extends AdminController
$response = [ $response = [
'image' => base_url('assets/images/product_image/' . $product['image']), 'image' => base_url('assets/images/product_image/' . $product['image']),
'nom' => $product['name'], 'nom' => $product['name'],
'ugs' => $product['sku'], 'num_serie' => $product['sku'],
'bill_no' => $data['bill_no'], 'bill_no' => $data['bill_no'],
'customer_name' => $order_data['customer_name'], 'customer_name' => $order_data['customer_name'],
'customer_address' => $order_data['customer_address'], 'customer_address' => $order_data['customer_address'],

View File

@ -24,15 +24,32 @@ class OrderItems extends Model
return $this->where('order_id', $order_id)->findAll(); return $this->where('order_id', $order_id)->findAll();
} }
public function getAllSoldProductToday() { public function getAllSoldProductToday($startDate = null, $endDate = null, $storeId = null, $userId = null) {
return $this->select(' $builder = $this->select('
COUNT(orders_item.id) as total_product_sold, COUNT(orders_item.id) as total_product_sold,
(SELECT SUM(products.qty) FROM products) as total_unsold_product (SELECT SUM(products.qty) FROM products) as total_unsold_product
') ')
->join('orders', 'orders_item.order_id = orders.id') ->join('orders', 'orders_item.order_id = orders.id');
->where('DATE(orders.date_time)', date('Y-m-d'))
->get() if (!empty($startDate) || !empty($endDate) || !empty($storeId) || !empty($userId)) {
->getRow(); if (!empty($startDate)) {
$builder->where('DATE(orders.date_time) >=', $startDate);
}
if (!empty($endDate)) {
$builder->where('DATE(orders.date_time) <=', $endDate);
}
} else {
$builder->where('DATE(orders.date_time)', date('Y-m-d'));
}
if (!empty($storeId)) {
$builder->where('orders.store_id', $storeId);
}
if (!empty($userId)) {
$builder->where('orders.user_id', $userId);
}
return $builder->get()->getRow();
} }
public function getSumOrdersItemData($order_id = null) public function getSumOrdersItemData($order_id = null)

View File

@ -124,6 +124,7 @@ class Orders extends Model
->join('orders_item', 'orders_item.order_id = orders.id', 'left') ->join('orders_item', 'orders_item.order_id = orders.id', 'left')
->join('products', 'products.id = orders_item.product_id', 'left') ->join('products', 'products.id = orders_item.product_id', 'left')
->select("IFNULL(GROUP_CONCAT(DISTINCT products.name SEPARATOR '\\n'), '') AS product_names", false) ->select("IFNULL(GROUP_CONCAT(DISTINCT products.name SEPARATOR '\\n'), '') AS product_names", false)
->select("COUNT(DISTINCT orders_item.id) AS item_count", false)
->groupBy('orders.id'); ->groupBy('orders.id');
// Récupération du groupe de l'utilisateur // Récupération du groupe de l'utilisateur
@ -387,7 +388,7 @@ class Orders extends Model
->findAll(); ->findAll();
} }
public function getPaymentModes($startDate = null, $endDate = null) public function getPaymentModes($startDate = null, $endDate = null, $storeId = null, $userId = null)
{ {
$session = session(); $session = session();
$users = $session->get('user'); $users = $session->get('user');
@ -464,10 +465,16 @@ class Orders extends Model
') ')
->whereIn('orders.paid_status', [1, 3]); ->whereIn('orders.paid_status', [1, 3]);
if (!$isAdmin) { if (!empty($storeId)) {
$baseQuery->where('orders.store_id', $storeId);
} elseif (!$isAdmin) {
$baseQuery->where('orders.store_id', $users['store_id']); $baseQuery->where('orders.store_id', $users['store_id']);
} }
if (!empty($userId)) {
$baseQuery->where('orders.user_id', $userId);
}
if ($startDate) { if ($startDate) {
$baseQuery->where('DATE(orders.date_time) >=', $startDate); $baseQuery->where('DATE(orders.date_time) >=', $startDate);
} }
@ -478,21 +485,47 @@ class Orders extends Model
return $baseQuery->get()->getRowObject(); return $baseQuery->get()->getRowObject();
} }
public function getTotalOrders() public function getTotalOrders($startDate = null, $endDate = null, $storeId = null, $userId = null)
{ {
return $this->db->table('orders') $builder = $this->db->table('orders')
->select(' COUNT(*) as total_orders') ->select('COUNT(*) as total_orders');
->get()
->getRow(); if (!empty($storeId)) {
$builder->where('store_id', $storeId);
}
if (!empty($userId)) {
$builder->where('user_id', $userId);
}
if (!empty($startDate)) {
$builder->where('DATE(date_time) >=', $startDate);
}
if (!empty($endDate)) {
$builder->where('DATE(date_time) <=', $endDate);
} }
public function getTotalOrderPerStore() return $builder->get()->getRow();
}
public function getTotalOrderPerStore($startDate = null, $endDate = null, $storeId = null, $userId = null)
{ {
return $this->db->table('orders') $builder = $this->db->table('orders')
->select('store_id, COUNT(*) as total') ->select('store_id, COUNT(*) as total')
->groupBy('store_id') ->groupBy('store_id');
->get()
->getResult(); if (!empty($storeId)) {
$builder->where('store_id', $storeId);
}
if (!empty($userId)) {
$builder->where('user_id', $userId);
}
if (!empty($startDate)) {
$builder->where('DATE(date_time) >=', $startDate);
}
if (!empty($endDate)) {
$builder->where('DATE(date_time) <=', $endDate);
}
return $builder->get()->getResult();
} }
public function getPaymentModesPercentage() public function getPaymentModesPercentage()
@ -556,35 +589,31 @@ class Orders extends Model
return $order; return $order;
} }
public function getTotalProductvente2(?int $id) public function getTotalProductvente2(?int $id, $startDate = null, $endDate = null)
{ {
$builder = $this->db->table('orders')
->select('orders.id, orders.paid_status, orders.store_id, orders.date_time, brands.name, products.name as Pname, products.sku')
->join('orders_item', 'orders.id = orders_item.order_id')
->join('products', 'orders_item.product_id = products.id')
->join('brands', 'brands.id = products.marque')
->whereIn('orders.paid_status', [1, 3]);
if ($id != 0) { if ($id != 0) {
$order = $this->db->table('orders') $builder->where('orders.store_id', $id);
->select('orders.id, orders.paid_status, orders.store_id, orders.date_time, brands.name, products.name as Pname, products.sku') }
->join('orders_item', 'orders.id = orders_item.order_id') if (!empty($startDate)) {
->join('products', 'orders_item.product_id = products.id') $builder->where('DATE(orders.date_time) >=', $startDate);
->join('brands', 'brands.id = products.marque') }
->whereIn('orders.paid_status', [1, 3]) // ← CHANGÉ ICI if (!empty($endDate)) {
->where('orders.store_id', $id) $builder->where('DATE(orders.date_time) <=', $endDate);
->get()
->getResult();
} else {
$order = $this->db->table('orders')
->select('orders.id, orders.paid_status, orders.store_id, orders.date_time, brands.name, products.name as Pname, products.sku')
->join('orders_item', 'orders.id = orders_item.order_id')
->join('products', 'orders_item.product_id = products.id')
->join('brands', 'brands.id = products.marque')
->whereIn('orders.paid_status', [1, 3]) // ← CHANGÉ ICI
->get()
->getResult();
} }
return $order; return $builder->get()->getResult();
} }
public function getOrderVendue() public function getOrderVendue($storeId = null, $startDate = null, $endDate = null)
{ {
$order = $this->db->table('products') $builder = $this->db->table('products')
->select(' ->select('
products.*, products.*,
products.name as Pname, products.name as Pname,
@ -595,14 +624,22 @@ class Orders extends Model
ELSE orders.gross_amount ELSE orders.gross_amount
END as totalNet, END as totalNet,
orders.date_time as DateTime orders.date_time as DateTime
', false) // ← MODIFIÉ ICI ', false)
->join('orders_item', 'products.id = orders_item.product_id') ->join('orders_item', 'products.id = orders_item.product_id')
->join('orders', 'orders_item.order_id = orders.id') ->join('orders', 'orders_item.order_id = orders.id')
->whereIn('orders.paid_status', [1, 3]) // ← ET ICI ->whereIn('orders.paid_status', [1, 3]);
->get()
->getResultArray();
return $order; if (!empty($storeId) && $storeId != 0) {
$builder->where('orders.store_id', $storeId);
}
if (!empty($startDate)) {
$builder->where('DATE(orders.date_time) >=', $startDate);
}
if (!empty($endDate)) {
$builder->where('DATE(orders.date_time) <=', $endDate);
}
return $builder->get()->getResultArray();
} }
public function getPerformanceByOrders($startDate = null, $endDate = null, $pvente = null, $commercialId = null) public function getPerformanceByOrders($startDate = null, $endDate = null, $pvente = null, $commercialId = null)

View File

@ -16,10 +16,9 @@ class Remise extends Model
$session = session(); $session = session();
$users = $session->get('user'); $users = $session->get('user');
// ✅ SUPERADMIN VOIT TOUTES LES DEMANDES "EN ATTENTE" (POUR VALIDATION) // ✅ SUPERADMIN VOIT TOUTES LES DEMANDES (TOUS STATUTS)
if ($users["group_name"] === "SuperAdmin") { if ($users["group_name"] === "SuperAdmin") {
return $this->where('demande_status', 'En attente') return $this->orderBy('date_demande', 'DESC')
->orderBy('date_demande', 'DESC')
->findAll(); ->findAll();
} }

View File

@ -39,13 +39,28 @@ class Reports extends Model
* @param mixed $year * @param mixed $year
* @return array<array> * @return array<array>
*/ */
public function getOrderData($year) public function getOrderData($year, $startDate = null, $endDate = null, $storeId = null, $userId = null)
{ {
if ($year) { if ($year) {
$months = $this->months(); $months = $this->months();
// Fetch orders with paid_status = 1 or 3 // Fetch orders with paid_status = 1 or 3
$result = $this->whereIn('paid_status', [1, 3])->findAll(); $builder = $this->whereIn('paid_status', [1, 3]);
if (!empty($storeId)) {
$builder->where('store_id', $storeId);
}
if (!empty($userId)) {
$builder->where('user_id', $userId);
}
if (!empty($startDate)) {
$builder->where('DATE(date_time) >=', $startDate);
}
if (!empty($endDate)) {
$builder->where('DATE(date_time) <=', $endDate);
}
$result = $builder->findAll();
$final_data = []; $final_data = [];
@ -56,11 +71,10 @@ class Reports extends Model
foreach ($result as $v) { foreach ($result as $v) {
$month_year = date('Y-m', strtotime($v['date_time'])); $month_year = date('Y-m', strtotime($v['date_time']));
if ($get_mon_year == $month_year) { if ($get_mon_year == $month_year) {
// Modifier le montant selon votre logique
if (!empty($v['discount']) && $v['discount'] > 0) { if (!empty($v['discount']) && $v['discount'] > 0) {
$v['amount_to_display'] = $v['discount']; // Utiliser le rabais $v['amount_to_display'] = $v['discount'];
} else { } else {
$v['amount_to_display'] = $v['gross_amount']; // Utiliser gross_amount $v['amount_to_display'] = $v['gross_amount'];
} }
$final_data[$get_mon_year][] = $v; $final_data[$get_mon_year][] = $v;
} }

View File

@ -13,8 +13,9 @@
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-md-12 col-xs-12"> <div class="col-md-12 col-xs-12">
<form class="form-inline" action="<?php echo base_url('reports/'); ?>" method="POST"> <form action="<?php echo base_url('reports/'); ?>" method="POST">
<div class="form-group"> <div class="row" style="margin-bottom: 15px;">
<div class="col-md-2">
<label for="select_year">Année</label> <label for="select_year">Année</label>
<select class="form-control" name="select_year" id="select_year"> <select class="form-control" name="select_year" id="select_year">
<?php foreach ($report_years as $value): ?> <?php foreach ($report_years as $value): ?>
@ -24,9 +25,47 @@
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
<button type="submit" class="btn btn-default">Envoyer</button> <div class="col-md-2">
<label for="start_date">Date début</label>
<input type="date" class="form-control" name="start_date" id="start_date" value="<?= $selected_start_date ?? '' ?>">
</div>
<div class="col-md-2">
<label for="end_date">Date fin</label>
<input type="date" class="form-control" name="end_date" id="end_date" value="<?= $selected_end_date ?? '' ?>">
</div>
<div class="col-md-2">
<label for="store_id">Point de vente</label>
<select class="form-control" name="store_id" id="store_id">
<option value="">TOUS</option>
<?php foreach ($stores as $store): ?>
<option value="<?= $store['id'] ?>" <?= (isset($selected_store_id) && $selected_store_id == $store['id']) ? 'selected' : '' ?>>
<?= $store['name'] ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-2">
<label for="user_id">Utilisateur</label>
<select class="form-control" name="user_id" id="user_id">
<option value="">TOUS</option>
<?php foreach ($users_list as $u): ?>
<option value="<?= $u['id'] ?>" <?= (isset($selected_user_id) && $selected_user_id == $u['id']) ? 'selected' : '' ?>>
<?= $u['firstname'] . ' ' . $u['lastname'] ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-2" style="padding-top: 25px;">
<button type="submit" class="btn btn-primary"><i class="fa fa-filter"></i> Filtrer</button>
<a href="<?= base_url('reports/') ?>" class="btn btn-default" title="Réinitialiser"><i class="fa fa-refresh"></i></a>
</div>
</div>
<div class="row" style="margin-bottom: 10px;">
<div class="col-md-12">
<a href="<?= base_url('reports/detail/stock') ?>" class="btn btn-sm btn-success">Details Stock</a> <a href="<?= base_url('reports/detail/stock') ?>" class="btn btn-sm btn-success">Details Stock</a>
<a href="<?= base_url('reports/detail/performance') ?>" class="btn btn-sm btn-primary">Performances</a> <a href="<?= base_url('reports/detail/performance') ?>" class="btn btn-sm btn-primary">Performances</a>
</div>
</div>
</form> </form>
</div> </div>

View File

@ -136,20 +136,27 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row g-3 align-items-center mb-4" style="margin: 5px 0 5px 5px;"> <div class="row g-3 align-items-center mb-4" style="margin: 5px 0 5px 5px;">
<div class="col-md-4"> <div class="col-md-3">
<label for="startDate" class="form-label">Date de début</label> <label for="startDate" class="form-label">Date de début</label>
<input type="date" id="startDate" class="form-control"> <input type="date" id="startDate" class="form-control">
</div> </div>
<div class="col-md-4"> <div class="col-md-3">
<label for="endDate" class="form-label">Date de fin</label> <label for="endDate" class="form-label">Date de fin</label>
<input type="date" id="endDate" class="form-control"> <input type="date" id="endDate" class="form-control">
</div> </div>
<div class="col-md-4 d-flex align-items-end"> <div class="col-md-3">
<label for="exportStoreFilter" class="form-label">Point de vente</label>
<select id="exportStoreFilter" class="form-control">
<option value="TOUS">TOUS</option>
<?php foreach ($stores as $value) { ?>
<option value="<?= $value['id'] ?>"><?= $value['name'] ?></option>
<?php } ?>
</select>
</div>
<div class="col-md-3 d-flex align-items-end">
<br> <br>
<button id="filteredB1" class="btn btn-primary w-100">Filtrer <button id="filteredB1" class="btn btn-primary w-100">Filtrer</button>
🔍</button> <button id="ExportBTN1" class="btn btn-success w-100">Exporter</button>
<button id="ExportBTN1" class="btn btn-success w-100">Exporter
📤</button>
</div> </div>
</div> </div>
@ -228,14 +235,16 @@
] ]
}); });
const filterBtn = document.getElementById('storeFilter'); const storeSelect = document.getElementById('storeFilter');
filterBtn.addEventListener('change', function () { storeSelect.addEventListener('change', function () {
let filterValue = filterBtn.value === "TOUS" ? "0" : filterBtn.value; let filterValue = storeSelect.value === "TOUS" ? "0" : storeSelect.value;
let startDate = $('#startDateStock').val();
let endDate = $('#endDateStock').val();
let params = '?startDate=' + startDate + '&endDate=' + endDate;
// Update the DataTable dynamically without reinitialization manageTable.ajax.url('fetchData/' + filterValue + params).load();
manageTable.ajax.url('fetchData/' + filterValue).load(); manageTable2.ajax.url('fetchDataStock/' + filterValue + params).load();
manageTable2.ajax.url('fetchDataStock/' + filterValue).load();
}); });
let productsSold = <?= $ventes ?>; let productsSold = <?= $ventes ?>;
@ -272,32 +281,14 @@
applyFilter("TOUS"); applyFilter("TOUS");
}); });
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex) {
if (settings.nTable.id !== 'export1') return true; // Apply only to your table
const startDate = $('#startDate').val();
const endDate = $('#endDate').val();
const saleDate = data[3]; // assuming column 4 is "Date de vente"
// If no start date, show everything (default)
if (!startDate) {
return true;
}
const sale = new Date(saleDate);
const start = new Date(startDate);
const end = endDate ? new Date(endDate) : null;
if (end) {
return sale >= start && sale <= end;
} else {
return sale >= start;
}
});
$('#filteredB1').on('click', function () { $('#filteredB1').on('click', function () {
manageTable3.draw(); // re-filter table let storeId = $('#exportStoreFilter').val();
let filterValue = storeId === "TOUS" ? "0" : storeId;
let startDate = $('#startDate').val();
let endDate = $('#endDate').val();
let params = '?startDate=' + startDate + '&endDate=' + endDate;
manageTable3.ajax.url('fetchDataStock2/' + filterValue + params).load();
}); });

View File

@ -308,7 +308,7 @@
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<p><strong>Produit :</strong> <span id="editNom"></span></p> <p><strong>Produit :</strong> <span id="editNom"></span></p>
<p><strong>UGS :</strong> <span id="editUgs"></span></p> <p><strong>SERIE :</strong> <span id="editNumSerie"></span></p>
<p><strong> Facture :</strong> <span id="editBillNo"></span></p> <p><strong> Facture :</strong> <span id="editBillNo"></span></p>
<p><strong>Client :</strong> <span id="editClient"></span></p> <p><strong>Client :</strong> <span id="editClient"></span></p>
<p><strong>Adresse :</strong> <span id="editAddress"></span></p> <p><strong>Adresse :</strong> <span id="editAddress"></span></p>
@ -353,8 +353,8 @@
<div class="col-xs-6"><span id="detailDesignation"></span></div> <div class="col-xs-6"><span id="detailDesignation"></span></div>
</div> </div>
<div class="row" style="margin-bottom: 15px;"> <div class="row" style="margin-bottom: 15px;">
<div class="col-xs-6"><strong>UGS:</strong></div> <div class="col-xs-6"><strong>SERIE:</strong></div>
<div class="col-xs-6"><span id="detailUGS"></span></div> <div class="col-xs-6"><span id="detailNumSerie"></span></div>
</div> </div>
<div class="row" style="margin-bottom: 15px;"> <div class="row" style="margin-bottom: 15px;">
<div class="col-xs-6"><strong>Marque:</strong></div> <div class="col-xs-6"><strong>Marque:</strong></div>
@ -430,7 +430,7 @@ $(function() {
}, },
columns: [ columns: [
{ data: 'image', orderable: false }, { data: 'image', orderable: false },
{ data: 'ugs' }, { data: 'num_serie' },
{ data: 'designation' }, { data: 'designation' },
{ data: 'statut' }, { data: 'statut' },
{ data: 'action', orderable: false } { data: 'action', orderable: false }
@ -462,7 +462,7 @@ $(function() {
success: function(response) { success: function(response) {
$('#editImage').attr('src', response.image); $('#editImage').attr('src', response.image);
$('#editNom').text(response.nom); $('#editNom').text(response.nom);
$('#editUgs').text(response.ugs); $('#editNumSerie').text(response.num_serie);
$('#editBillNo').text(response.bill_no); $('#editBillNo').text(response.bill_no);
$('#editClient').text(response.customer_name); $('#editClient').text(response.customer_name);
$('#editAddress').text(response.customer_address); $('#editAddress').text(response.customer_address);
@ -767,7 +767,7 @@ $(function() {
data.push([ data.push([
'N° Facture', 'N° Facture',
'Désignation', 'Désignation',
'UGS', 'N° SERIE',
'Marque', 'Marque',
'Client', 'Client',
'Magasin', 'Magasin',
@ -818,7 +818,7 @@ function viewDetails(id) {
$('#detailImage').attr('src', data[0]); $('#detailImage').attr('src', data[0]);
$('#detailBillNo').text(data[1]); $('#detailBillNo').text(data[1]);
$('#detailDesignation').text(data[2]); $('#detailDesignation').text(data[2]);
$('#detailUGS').text(data[3]); $('#detailNumSerie').text(data[3]);
$('#detailMarque').text(data[4]); $('#detailMarque').text(data[4]);
$('#detailSerie').text(data[3]); $('#detailSerie').text(data[3]);
$('#detailStore').text(data[7]); $('#detailStore').text(data[7]);