diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 963d73fd..86209a30 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -184,6 +184,7 @@ $routes->group('', ['filter' => 'auth'], function ($routes) {
$routes->group('/orders', function ($routes) {
$routes->get('/', [OrderController::class, 'index']);
$routes->get('fetchOrdersData', [OrderController::class, 'fetchOrdersData']);
+ $routes->get('editAsNew/(:num)', 'OrderController::editAsNew/$1');
$routes->get('create', [OrderController::class, 'create']);
$routes->post('create', [OrderController::class, 'create']);
$routes->post('getProductValueById', [OrderController::class, 'getProductValueById']);
@@ -194,11 +195,12 @@ $routes->group('', ['filter' => 'auth'], function ($routes) {
$routes->get('printDivBL/(:num)', [OrderController::class, 'print7']);
$routes->get('printDivBLF/(:num)', [OrderController::class, 'print31']);
$routes->post('remove', [OrderController::class, 'remove']);
+ $routes->post('markAsDelivered', [OrderController::class, 'markAsDelivered']); // ← AJOUTEZ CETTE LIGNE ICI
$routes->get('lookOrder/(:num)', [OrderController::class, 'lookOrder']);
$routes->get('createFromEspace/(:num)', [OrderController::class, 'createById']);
$routes->get('resrevation', [ReservationController::class, 'index']);
+
});
-
/**
* route for the reports
*/
@@ -261,19 +263,25 @@ $routes->group('', ['filter' => 'auth'], function ($routes) {
$routes->post('markAsRead/(:num)', [NotificationController::class, 'markAsRead']);
});
// routes for sortie caisse
- $routes->group('/sortieCaisse', function ($routes) {
- $routes->get('/', [SortieCaisseController::class, 'index']);
- $routes->get('fetchSortieCaisseData', [SortieCaisseController::class, 'fetchSortieCaisseData']);
- $routes->get('fetchSortieCaisseData1', [SortieCaisseController::class, 'fetchSortieCaisseData1']);
- $routes->post('fetchSortieCaisseSingle/(:num)', [SortieCaisseController::class, 'fetchSortieCaisseSingle']);
- $routes->post('createSortieCaisse', [SortieCaisseController::class, 'createSortieCaisse']);
- // $routes->post('delete', [RecouvrementController::class, 'removeRecouvrement']);
- $routes->post('updateSortieCaisse/(:num)', [SortieCaisseController::class, 'updateSortieCaisse']);
- $routes->post('validateSortieCaisse/(:num)', [SortieCaisseController::class, 'validateSortieCaisse']);
- });
+$routes->group('/sortieCaisse', function ($routes) {
+ $routes->get('/', [SortieCaisseController::class, 'index']);
+ $routes->get('fetchSortieCaisseData', [SortieCaisseController::class, 'fetchSortieCaisseData']);
+ $routes->get('fetchSortieCaisseData1', [SortieCaisseController::class, 'fetchSortieCaisseData1']);
+ $routes->post('fetchSortieCaisseSingle/(:num)', [SortieCaisseController::class, 'fetchSortieCaisseSingle']);
+ $routes->post('createSortieCaisse', [SortieCaisseController::class, 'createSortieCaisse']);
+ $routes->post('markAsPaid/(:num)', 'SortieCaisseController::markAsPaid/$1');
+ $routes->post('updateSortieCaisse/(:num)', [SortieCaisseController::class, 'updateSortieCaisse']);
+ $routes->post('validateSortieCaisse/(:num)', [SortieCaisseController::class, 'validateSortieCaisse']);
+
+ // ✅ Routes d'exportation
+ $routes->get('exportExcel', [SortieCaisseController::class, 'exportExcel']);
+ $routes->get('exportCsv', [SortieCaisseController::class, 'exportCsv']);
+ $routes->get('exportWithFilters', [SortieCaisseController::class, 'exportWithFilters']);
+});
// remise
$routes->group('/remise', function ($routes) {
+ $routes->get('', [RemiseController::class, 'index']);
$routes->get('/', [RemiseController::class, 'index']);
$routes->get('fetchRemiseData', [RemiseController::class, 'fetchRemiseData']);
// $routes->post('delete', [RecouvrementController::class, 'removeRecouvrement']);
diff --git a/app/Controllers/AvanceController.php b/app/Controllers/AvanceController.php
index 1da9c316..69bb6394 100644
--- a/app/Controllers/AvanceController.php
+++ b/app/Controllers/AvanceController.php
@@ -63,19 +63,25 @@ class AvanceController extends AdminController
. '';
}
+
return $buttons;
}
private function buildDataRow($value, $product, $isAdmin, $isCommerciale, $isCaissier, $buttons)
{
$date_time = date('d-m-Y h:i a', strtotime($value['avance_date']));
+
+ // ✅ Afficher product_name si disponible, sinon récupérer depuis la BDD
+ $productName = !empty($value['product_name'])
+ ? $value['product_name']
+ : $product->getProductNameById($value['product_id']);
if ($isAdmin) {
return [
$value['customer_name'],
$value['customer_phone'],
$value['customer_address'],
- $product->getProductNameById($value['product_id']),
+ $productName, // ✅ Utiliser la variable
number_format((int)$value['gross_amount'], 0, ',', ' '),
number_format((int)$value['avance_amount'], 0, ',', ' '),
number_format((int)$value['amount_due'], 0, ',', ' '),
@@ -85,7 +91,7 @@ class AvanceController extends AdminController
} elseif ($isCommerciale || $isCaissier) {
return [
$value['avance_id'],
- $product->getProductNameById($value['product_id']),
+ $productName, // ✅ Utiliser la variable
number_format((int)$value['avance_amount'], 0, ',', ' '),
number_format((int)$value['amount_due'], 0, ',', ' '),
$date_time,
@@ -354,14 +360,14 @@ class AvanceController extends AdminController
public function createAvance()
{
$this->verifyRole('createAvance');
-
+
if ($this->request->getMethod() !== 'post') {
return $this->response->setJSON([
'success' => false,
'messages' => 'Méthode non autorisée'
]);
}
-
+
try {
$session = session();
$users = $session->get('user');
@@ -369,37 +375,51 @@ class AvanceController extends AdminController
$Avance = new Avance();
$Products = new Products();
$Notification = new NotificationController();
-
+
+ // ✅ Récupérer le type AVANT la validation
+ $type_avance = $this->request->getPost('type_avance');
+
+ // ✅ Validation conditionnelle
$validation = \Config\Services::validation();
- $validation->setRules([
+
+ $baseRules = [
'customer_name_avance' => 'required|min_length[2]',
'customer_phone_avance' => 'required',
'customer_address_avance' => 'required',
'customer_cin_avance' => 'required',
- 'id_product' => 'required|numeric',
+ 'gross_amount' => 'required|numeric|greater_than[0]',
'avance_amount' => 'required|numeric|greater_than[0]',
- 'type_avance' => 'required|in_list[terre,mere]'
- ]);
-
+ 'type_avance' => 'required|in_list[terre,mere]',
+ 'type_payment' => 'required'
+ ];
+
+ if ($type_avance === 'mere') {
+ $baseRules['product_name_text'] = 'required|min_length[2]';
+ } else {
+ $baseRules['id_product'] = 'required|numeric';
+ }
+
+ $validation->setRules($baseRules);
+
if (!$validation->withRequest($this->request)->run()) {
return $this->response->setJSON([
'success' => false,
'messages' => 'Données invalides: ' . implode(', ', $validation->getErrors())
]);
}
-
+
$avance_date = date('Y-m-d H:i:s');
-
- // Calcul automatique de la deadline selon le type d'avance
- $type_avance = $this->request->getPost('type_avance');
+
+ // Calcul de la deadline
if ($type_avance === 'terre') {
$deadline = date('Y-m-d', strtotime($avance_date . ' +15 days'));
} elseif ($type_avance === 'mere') {
$deadline = date('Y-m-d', strtotime($avance_date . ' +2 months'));
} else {
- $deadline = null; // fallback si jamais
+ $deadline = null;
}
-
+
+ // Préparer les données communes
$data = [
'type_avance' => $type_avance,
'type_payment' => $this->request->getPost('type_payment'),
@@ -411,16 +431,30 @@ class AvanceController extends AdminController
'deadline' => $deadline,
'user_id' => $users['id'],
'store_id' => $users['store_id'],
- 'product_id' => (int)$this->request->getPost('id_product'),
'gross_amount' => (float)$this->request->getPost('gross_amount'),
'avance_amount' => (float)$this->request->getPost('avance_amount'),
- 'amount_due' => (float)$this->request->getPost('amount_due'),
+ 'amount_due' => (float)$this->request->getPost('gross_amount') - (float)$this->request->getPost('avance_amount'),
'is_order' => 0,
'active' => 1,
];
-
+
+ // ✅ Ajouter le produit selon le type
+ if ($type_avance === 'mere') {
+ $data['product_name'] = $this->request->getPost('product_name_text');
+ // $data['product_id'] = null;
+ $data['commentaire'] = $this->request->getPost('commentaire');
+ } else {
+ $data['product_id'] = (int)$this->request->getPost('id_product');
+ $data['product_name'] = null;
+ $data['commentaire'] = null;
+ }
+
if ($avance_id = $Avance->createAvance($data)) {
- $Products->update($data['product_id'], ['product_sold' => 1]);
+
+ // ✅ Marquer le produit comme vendu UNIQUEMENT pour "terre"
+ if ($type_avance === 'terre' && !empty($data['product_id'])) {
+ $Products->update($data['product_id'], ['product_sold' => 1]);
+ }
$Notification->createNotification(
'Une nouvelle avance a été créée',
@@ -444,10 +478,11 @@ class AvanceController extends AdminController
log_message('error', "Erreur création avance: " . $e->getMessage());
return $this->response->setJSON([
'success' => false,
- 'messages' => 'Une erreur interne est survenue'
+ 'messages' => 'Une erreur interne est survenue: ' . $e->getMessage()
]);
}
}
+
public function updateAvance()
{
$this->verifyRole('updateAvance');
@@ -467,18 +502,31 @@ class AvanceController extends AdminController
$Products = new Products();
$Notification = new NotificationController();
- // Validation des données (avec les vrais noms des champs du formulaire)
+ // ✅ Récupérer le type AVANT la validation
+ $type_avance = $this->request->getPost('type_avance_edit');
+
+ // ✅ Validation conditionnelle selon le type
$validation = \Config\Services::validation();
- $validation->setRules([
+
+ $baseRules = [
'id' => 'required|numeric',
'customer_name_avance_edit' => 'required|min_length[2]',
'customer_phone_avance_edit' => 'required',
'customer_address_avance_edit' => 'required',
'customer_cin_avance_edit' => 'required',
- 'id_product_edit' => 'required|numeric',
+ 'gross_amount_edit' => 'required|numeric|greater_than[0]',
'avance_amount_edit' => 'required|numeric|greater_than[0]',
- 'type_avance_edit' => 'required|in_list[terre,mere]'
- ]);
+ 'type_avance_edit' => 'required|in_list[terre,mere]',
+ 'type_payment_edit' => 'required'
+ ];
+
+ if ($type_avance === 'mere') {
+ $baseRules['product_name_text_edit'] = 'required|min_length[2]';
+ } else {
+ $baseRules['id_product_edit'] = 'required|numeric';
+ }
+
+ $validation->setRules($baseRules);
if (!$validation->withRequest($this->request)->run()) {
return $this->response->setJSON([
@@ -487,7 +535,7 @@ class AvanceController extends AdminController
]);
}
- $avance_id = $this->request->getPost('id'); // Changement ici
+ $avance_id = $this->request->getPost('id');
// Vérifier si l'avance existe
$existingAvance = $Avance->fetchSingleAvance($avance_id);
@@ -510,10 +558,8 @@ class AvanceController extends AdminController
}
// Recalculer la deadline si le type d'avance a changé
- $type_avance = $this->request->getPost('type_avance_edit'); // Changement ici
$current_deadline = $existingAvance['deadline'];
- // Si le type a changé, recalculer la deadline
if ($type_avance !== $existingAvance['type_avance']) {
if ($type_avance === 'terre') {
$current_deadline = date('Y-m-d', strtotime($existingAvance['avance_date'] . ' +15 days'));
@@ -523,34 +569,54 @@ class AvanceController extends AdminController
}
$old_product_id = $existingAvance['product_id'];
- $new_product_id = (int)$this->request->getPost('id_product_edit'); // Changement ici
+ // Préparer les données communes
$data = [
'type_avance' => $type_avance,
- 'type_payment' => $this->request->getPost('type_payment_edit'), // Changement ici
- 'customer_name' => $this->request->getPost('customer_name_avance_edit'), // Changement ici
- 'customer_address' => $this->request->getPost('customer_address_avance_edit'), // Changement ici
- 'customer_phone' => $this->request->getPost('customer_phone_avance_edit'), // Changement ici
- 'customer_cin' => $this->request->getPost('customer_cin_avance_edit'), // Changement ici
+ 'type_payment' => $this->request->getPost('type_payment_edit'),
+ 'customer_name' => $this->request->getPost('customer_name_avance_edit'),
+ 'customer_address' => $this->request->getPost('customer_address_avance_edit'),
+ 'customer_phone' => $this->request->getPost('customer_phone_avance_edit'),
+ 'customer_cin' => $this->request->getPost('customer_cin_avance_edit'),
'deadline' => $current_deadline,
- 'product_id' => $new_product_id,
- 'gross_amount' => (float)$this->request->getPost('gross_amount_edit'), // Changement ici
- 'avance_amount' => (float)$this->request->getPost('avance_amount_edit'), // Changement ici
- 'amount_due' => (float)$this->request->getPost('amount_due_edit'), // Changement ici
+ 'gross_amount' => (float)$this->request->getPost('gross_amount_edit'),
+ 'avance_amount' => (float)$this->request->getPost('avance_amount_edit'),
+ 'amount_due' => (float)$this->request->getPost('amount_due_edit'),
];
+ // ✅ Gérer le produit selon le type
+ if ($type_avance === 'mere') {
+ $data['product_name'] = $this->request->getPost('product_name_text_edit');
+ $data['product_id'] = null; // ⚠️ Sera NULL si la colonne l'accepte
+ $data['commentaire'] = $this->request->getPost('commentaire_edit');
+ $new_product_id = null;
+ } else {
+ $new_product_id = (int)$this->request->getPost('id_product_edit');
+ $data['product_id'] = $new_product_id;
+ $data['product_name'] = null;
+ $data['commentaire'] = null;
+ }
+
// Mettre à jour l'avance
if ($Avance->updateAvance($avance_id, $data)) {
- // Gérer le changement de produit si nécessaire
- if ($old_product_id !== $new_product_id) {
- // Libérer l'ancien produit
- $Products->update($old_product_id, ['product_sold' => 0]);
- // Marquer le nouveau produit comme vendu
- $Products->update($new_product_id, ['product_sold' => 1]);
+ // ✅ Gérer le changement de produit UNIQUEMENT pour "terre"
+ if ($type_avance === 'terre') {
+ if ($old_product_id && $old_product_id !== $new_product_id) {
+ // Libérer l'ancien produit
+ $Products->update($old_product_id, ['product_sold' => 0]);
+ }
+ if ($new_product_id) {
+ // Marquer le nouveau produit comme vendu
+ $Products->update($new_product_id, ['product_sold' => 1]);
+ }
+ } else {
+ // Si on passe de "terre" à "mere", libérer l'ancien produit
+ if ($old_product_id && $existingAvance['type_avance'] === 'terre') {
+ $Products->update($old_product_id, ['product_sold' => 0]);
+ }
}
- // Créer une notification
$Notification->createNotification(
'Une avance a été modifiée',
"Conseil",
@@ -574,11 +640,12 @@ class AvanceController extends AdminController
log_message('error', "Erreur modification avance: " . $e->getMessage());
return $this->response->setJSON([
'success' => false,
- 'messages' => 'Une erreur interne est survenue'
+ 'messages' => 'Une erreur interne est survenue: ' . $e->getMessage()
]);
}
}
-
+
+
public function removeAvance()
{
$this->verifyRole('deleteAvance');
diff --git a/app/Controllers/Dashboard.php b/app/Controllers/Dashboard.php
index 3210d8fc..f7266b7d 100644
--- a/app/Controllers/Dashboard.php
+++ b/app/Controllers/Dashboard.php
@@ -10,6 +10,7 @@ use App\Models\Stores;
use App\Models\Users;
use App\Models\Recouvrement;
use App\Models\SortieCaisse;
+
class Dashboard extends AdminController
{
@@ -32,71 +33,78 @@ class Dashboard extends AdminController
$totalRecouvrement = $Recouvrement->getTotalRecouvrements();
$sortieCaisse = new SortieCaisse();
$total_sortie_caisse = $sortieCaisse->getTotalSortieCaisse();
- $total_sortie_caisse1= $total_sortie_caisse->mr;
- // Recouvrements
- $total_recouvrement_me = $totalRecouvrement->me;
- $total_recouvrement_bm = $totalRecouvrement->bm;
- $total_recouvrement_be = $totalRecouvrement->be;
- $total_recouvrement_mb = $totalRecouvrement->mb;
+ // === EXTRACTION DES SORTIES PAR MODE DE PAIEMENT ===
+ $total_sortie_espece = isset($total_sortie_caisse->total_espece) ? (float) $total_sortie_caisse->total_espece : 0;
+ $total_sortie_mvola = isset($total_sortie_caisse->total_mvola) ? (float) $total_sortie_caisse->total_mvola : 0;
+ $total_sortie_virement = isset($total_sortie_caisse->total_virement) ? (float) $total_sortie_caisse->total_virement : 0;
+
+ // === TOTAUX RECOUVREMENT ===
+ $me = isset($totalRecouvrement->me) ? (float) $totalRecouvrement->me : 0;
+ $bm = isset($totalRecouvrement->bm) ? (float) $totalRecouvrement->bm : 0;
+ $be = isset($totalRecouvrement->be) ? (float) $totalRecouvrement->be : 0;
+ $mb = isset($totalRecouvrement->mb) ? (float) $totalRecouvrement->mb : 0;
// Avances
$Avance = new Avance();
$totalAvance = $Avance->getTotalAvance();
$paymentDataAvance = $Avance->getPaymentModesAvance();
- // Initialisation des totaux Orders (en utilisant les bonnes propriétés)
- $total_orders = isset($paymentData->total) ? $paymentData->total : 0;
- $total_mvola1_orders = isset($paymentData->total_mvola1) ? $paymentData->total_mvola1 : 0;
- $total_mvola2_orders = isset($paymentData->total_mvola2) ? $paymentData->total_mvola2 : 0;
- $total_espece1_orders = isset($paymentData->total_espece1) ? $paymentData->total_espece1 : 0;
- $total_espece2_orders = isset($paymentData->total_espece2) ? $paymentData->total_espece2 : 0;
- $total_virement_bancaire1_orders = isset($paymentData->total_virement_bancaire1) ? $paymentData->total_virement_bancaire1 : 0;
- $total_virement_bancaire2_orders = isset($paymentData->total_virement_bancaire2) ? $paymentData->total_virement_bancaire2 : 0;
-
- // Initialisation des totaux Avances (utiliser les bonnes propriétés de getPaymentModesAvance)
- $total_avances = isset($paymentDataAvance->total) ? $paymentDataAvance->total : 0;
- $total_mvola_avances = isset($paymentDataAvance->total_mvola) ? $paymentDataAvance->total_mvola : 0;
- $total_espece_avances = isset($paymentDataAvance->total_espece) ? $paymentDataAvance->total_espece : 0;
- $total_virement_bancaire_avances = isset($paymentDataAvance->total_virement_bancaire) ? $paymentDataAvance->total_virement_bancaire : 0;
-
- // Addition Orders + Avances
+ // === TOTAUX PAIEMENTS ORDERS ===
+ $total_orders = isset($paymentData->total) ? (float) $paymentData->total : 0;
+ $mv1_orders = isset($paymentData->total_mvola1) ? (float) $paymentData->total_mvola1 : 0;
+ $mv2_orders = isset($paymentData->total_mvola2) ? (float) $paymentData->total_mvola2 : 0;
+ $es1_orders = isset($paymentData->total_espece1) ? (float) $paymentData->total_espece1 : 0;
+ $es2_orders = isset($paymentData->total_espece2) ? (float) $paymentData->total_espece2 : 0;
+ $vb1_orders = isset($paymentData->total_virement_bancaire1) ? (float) $paymentData->total_virement_bancaire1 : 0;
+ $vb2_orders = isset($paymentData->total_virement_bancaire2) ? (float) $paymentData->total_virement_bancaire2 : 0;
+
+ // === TOTAUX PAIEMENTS AVANCES ===
+ $total_avances = isset($paymentDataAvance->total) ? (float) $paymentDataAvance->total : 0;
+ $mv_avances = isset($paymentDataAvance->total_mvola) ? (float) $paymentDataAvance->total_mvola : 0;
+ $es_avances = isset($paymentDataAvance->total_espece) ? (float) $paymentDataAvance->total_espece : 0;
+ $vb_avances = isset($paymentDataAvance->total_virement_bancaire) ? (float) $paymentDataAvance->total_virement_bancaire : 0;
+
+ // === COMBINAISON ORDERS + AVANCES ===
+ $total_mvola = $mv1_orders + $mv2_orders + $mv_avances;
+ $total_espece = $es1_orders + $es2_orders + $es_avances;
+ $total_vb = $vb1_orders + $vb2_orders + $vb_avances;
$total = $total_orders + $total_avances;
- // Combiner les totaux par type de paiement
- $total_mvola1 = $total_mvola1_orders;
- $total_mvola2 = $total_mvola2_orders;
- $total_espece1 = $total_espece1_orders;
- $total_espece2 = $total_espece2_orders;
- $total_virement_bancaire1 = $total_virement_bancaire1_orders;
- $total_virement_bancaire2 = $total_virement_bancaire2_orders;
-
- // Totaux combinés Orders
- $total_mvola_orders_combined = $total_mvola1 + $total_mvola2;
- $total_espece_orders_combined = $total_espece1 + $total_espece2;
- $total_virement_bancaire_orders_combined = $total_virement_bancaire1 + $total_virement_bancaire2;
-
- // Totaux finaux (Orders + Avances)
- $total_mvola = $total_mvola_orders_combined + $total_mvola_avances;
- $total_espece = $total_espece_orders_combined + $total_espece_avances;
- $total_virement_bancaire = $total_virement_bancaire_orders_combined + $total_virement_bancaire_avances;
-
- // Ajustements avec les recouvrements et sorties caisse
- $total_mvola_final = $total_mvola - $total_recouvrement_me - $total_recouvrement_mb + $total_recouvrement_bm;
- $total_espece_final = $total_espece + $total_recouvrement_me + $total_recouvrement_be - $total_sortie_caisse1;
- $total_virement_bancaire_final = $total_virement_bancaire - $total_recouvrement_be - $total_recouvrement_bm + $total_recouvrement_mb;
+ // === AJUSTEMENTS AVEC RECOUVREMENTS ET SORTIES (PAR MODE DE PAIEMENT) ===
+ $total_mvola_final = $total_mvola -
+ $me -
+ $mb +
+ $bm -
+ $total_sortie_mvola;
+ $total_espece_final = $total_espece +
+ $me +
+ $be -
+ $total_sortie_espece;
+
+ $total_virement_bancaire_final = $total_vb -
+ $be -
+ $bm +
+ $mb -
+ $total_sortie_virement;
+
+ // === CALCUL DU TOTAL GÉNÉRAL ===
+ // ✅ CORRECTION: Ne PAS additionner les recouvrements au total
+ // Les recouvrements sont des transferts internes, pas des entrées d'argent
+ $total_sortie_global = $total_sortie_espece + $total_sortie_mvola + $total_sortie_virement;
+ $total_final = $total - $total_sortie_global;
+
// check avance expired
$avance = new Avance();
$avance->checkExpiredAvance();
-
+
$data = [
- 'total' => $total,
+ 'total' => $total_final,
'total_mvola' => $total_mvola_final,
'total_espece' => $total_espece_final,
'total_virement_bancaire' => $total_virement_bancaire_final,
'user_permission' => $this->permission,
-
];
$data['total_products'] = $productModel->countTotalProducts();
@@ -144,10 +152,10 @@ class Dashboard extends AdminController
// filter to keep non empty array
$filteredArray = array_filter($newData, function($item) {
- return !empty($item); // Keep only non-empty arrays
+ return !empty($item);
});
- // Re-index the array (optional, if you want sequential keys)
+ // Re-index the array
$userWhoSoldProducts = array_values($filteredArray);
// Count occurrences of each userId
@@ -166,6 +174,7 @@ class Dashboard extends AdminController
}
$data['count_id'] = $countId;
+
// Check if the user is an Conseil
$session = session();
$user_id = $session->get('user');
@@ -174,6 +183,7 @@ class Dashboard extends AdminController
$data['isChef'] = false;
$data['isCaissier'] = false;
$data['isMecanicien'] = false;
+
if ($user_id['group_name'] == "Direction" || $user_id['group_name'] == "Conseil") {
$data['is_admin'] = true;
}
@@ -186,16 +196,18 @@ class Dashboard extends AdminController
}
if ($user_id['group_name'] == "Cheffe d'Agence") {
$data['isChef'] = true;
- }
+ }
if ($user_id['group_name'] == "Caissière") {
$data['isCaissier'] = true;
}
if ($user_id['group_name'] == "MECANICIEN") {
$data['isMecanicien'] = true;
}
+
$data['page_title'] = 'Dashboard';
$data['marques_total'] = json_encode($orderModel->getTotalProductvente());
$data['marques'] = json_encode($Brancds->getName());
+
$Orders = new Orders();
$Products = new Products();
$Stores = new Stores();
diff --git a/app/Controllers/NotificationController.php b/app/Controllers/NotificationController.php
index 49222b02..b271602b 100644
--- a/app/Controllers/NotificationController.php
+++ b/app/Controllers/NotificationController.php
@@ -11,30 +11,30 @@ class NotificationController extends AdminController
parent::__construct();
}
+ // Récupérer toutes les notifications selon les règles définies dans le modèle
public function getNotification()
{
$Notification = new Notification();
-
$notifications = $Notification->getNotifications();
-
return $this->response->setJSON($notifications);
}
+ // Marquer une notification comme lue
public function markAsRead(int $id)
{
$Notification = new Notification();
$Notification->markAsRead($id);
-
return $this->response->setJSON(['status' => 'success']);
}
+ // Créer une nouvelle notification
public function createNotification(string $message, string $group, ?int $store_id, ?string $link)
{
$Notification = new Notification();
$data = [
'message' => $message,
- 'is_read' => 0,
+ 'is_read' => 0,
'forgroup' => $group,
'store_id' => $store_id,
'link' => $link,
diff --git a/app/Controllers/OrderController.php b/app/Controllers/OrderController.php
index 82e6c660..b206a79c 100644
--- a/app/Controllers/OrderController.php
+++ b/app/Controllers/OrderController.php
@@ -14,6 +14,8 @@ use App\Models\Products;
use App\Models\Attributes;
use App\Models\OrderItems;
use App\Models\Remise;
+use App\Models\FourchettePrix;
+
use PhpParser\Node\Stmt\Else_;
@@ -36,27 +38,27 @@ class OrderController extends AdminController
public function fetchOrdersData()
{
- // Load the required helpers
helper(['url', 'form']);
$Orders = new Orders();
$result = ['data' => []];
- // Fetch orders data from the model
$data = $Orders->getOrdersData();
$session = session();
$users = $session->get('user');
- if($users['group_name'] == "Caissière"){
+
+ if ($users['group_name'] == "Caissière") {
foreach ($data as $key => $value) {
- // $count_total_item = $Orders->countOrderItem($value['id']);
- $date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); // Combine date and time formatting
+ $date_time = date('d-m-Y h:i a', strtotime($value['date_time']));
- // Initialize buttons
$buttons = '';
- if (in_array('viewOrder', $this->permission)) {
+ // Bouton imprimer (sauf pour SECURITE)
+ if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") {
$buttons .= '';
}
+
+ // Bouton voir
if (in_array('viewOrder', $this->permission)) {
$buttons .= '
';
}
+ // Bouton modifier
if (in_array('updateOrder', $this->permission) && $users["store_id"] == $value['store_id']) {
$buttons .= ' ';
}
- // Paid status label
- $paid_status = ($value['paid_status'] == 1)
- ? 'Payé'
- : 'Non payé';
+ // Statut de paiement
+ if ($value['paid_status'] == 1) {
+ $paid_status = 'Validé';
+ } elseif ($value['paid_status'] == 2) {
+ $paid_status = 'En Attente';
+ } elseif ($value['paid_status'] == 3) {
+ $paid_status = 'Validé et Livré';
+ } else {
+ $paid_status = 'Refusé';
+ }
+ // Calcul délai (SANS notification ici)
$date1 = new DateTime($date_time);
- $date2 = new DateTime(); // Current date and time
-
- // Calculate the difference in days
+ $date2 = new DateTime();
$interval = $date1->diff($date2);
$daysPassed = $interval->days;
- $statuDate = '';
- // die(var_dump($daysPassed));
- $Notification = new NotificationController();
- // die(var_dump($_SERVER['REQUEST_URI'] == "/orders/fetchOrdersData"));
- $uri = $_SERVER['REQUEST_URI'];
- if ($daysPassed < 8 && $value['paid_status'] == 2) {
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
- } else if ($daysPassed >= 8 && $value['paid_status'] == 2) {
- $Notification->createNotification("Conseil : Confirmation de reservation", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
- } else if ($daysPassed >= 15 && $value['paid_status'] == 2) {
- $Notification->createNotification("Conseil : Reservation expiré", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ $statuDate = '';
+ if ($value['paid_status'] == 2) {
+ if ($daysPassed < 8) {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ } elseif ($daysPassed >= 8 && $daysPassed < 15) {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ } else {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ }
}
- $Orders_items= new OrderItems();
- $sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
- // Add data to the result array
+ // $Orders_items = new OrderItems();
+ // $sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
+
$result['data'][$key] = [
$value['product_names'],
$value['user_name'],
$date_time . "
" . $statuDate,
- $sum_order_item,
- number_format((int) $value['net_amount'], 0, ',', ' '),
+ number_format((int) $value['discount'], 0, ',', ' '),
+ number_format((int) $value['gross_amount'], 0, ',', ' '),
$paid_status,
$buttons
];
}
return $this->response->setJSON($result);
- }
- else if($users['group_name'] == "Direction" || $users['group_name'] == "Conseil"){
+ }
+
+ elseif($users['group_name'] == "Direction" || $users['group_name'] == "DAF"){
foreach ($data as $key => $value) {
- // $count_total_item = $Orders->countOrderItem($value['id']);
- $date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); // Combine date and time formatting
+ $date_time = date('d-m-Y h:i a', strtotime($value['date_time']));
- // Initialize buttons
$buttons = '';
- if (in_array('viewOrder', $this->permission)) {
+ // Bouton imprimer (sauf pour SECURITE)
+ if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") {
$buttons .= '';
}
+
if (in_array('updateOrder', $this->permission)) {
$buttons .= ' ';
@@ -135,66 +140,70 @@ class OrderController extends AdminController
$buttons .= ' ';
}
- // Paid status label
- $paid_status = ($value['paid_status'] == 1)
- ? 'Payé'
- : 'Non payé';
+
- $date1 = new DateTime($date_time);
- $date2 = new DateTime(); // Current date and time
+
+ // Statut de paiement
+ if ($value['paid_status'] == 1) {
+ $paid_status = 'Validé';
+ } elseif ($value['paid_status'] == 2) {
+ $paid_status = 'En Attente';
+ } elseif ($value['paid_status'] == 3) {
+ $paid_status = 'Validé et Livré';
+ } else {
+ $paid_status = 'Refusé';
+ }
- // Calculate the difference in days
+ // Calcul délai (SANS notification)
+ $date1 = new DateTime($date_time);
+ $date2 = new DateTime();
$interval = $date1->diff($date2);
$daysPassed = $interval->days;
- $statuDate = '';
- // die(var_dump($daysPassed));
- $Notification = new NotificationController();
- // die(var_dump($_SERVER['REQUEST_URI'] == "/orders/fetchOrdersData"));
- $uri = $_SERVER['REQUEST_URI'];
- if ($daysPassed < 8 && $value['paid_status'] == 2) {
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
- } else if ($daysPassed >= 8 && $value['paid_status'] == 2) {
- $Notification->createNotification("Conseil : Confirmation de reservation", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
- } else if ($daysPassed >= 15 && $value['paid_status'] == 2) {
- $Notification->createNotification("Conseil : Reservation expiré", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ $statuDate = '';
+ if ($value['paid_status'] == 2) {
+ if ($daysPassed < 8) {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ } elseif ($daysPassed >= 8 && $daysPassed < 15) {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ } else {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ }
}
- $Orders_items= new OrderItems();
- $sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
- // Add data to the result array
+ // $Orders_items= new OrderItems();
+ // $sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
+
$result['data'][$key] = [
$value['bill_no'],
$value['customer_name'],
$value['customer_phone'],
$date_time . "
" . $statuDate,
- $sum_order_item,
- number_format((int) $value['net_amount'], 0, ',', ' '),
+ number_format((int) $value['discount'], 0, ',', ' '),
+ number_format((int) $value['gross_amount'], 0, ',', ' '),
$paid_status,
$buttons
];
}
return $this->response->setJSON($result);
- }
- else {
- if($users['group_name'] !== "Direction" || $users['group_name'] !== "Conseil"){
+ }
+ else {
foreach ($data as $key => $value) {
-
- // $count_total_item = $Orders->countOrderItem($value['id']);
- $date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); // Combine date and time formatting
+ $date_time = date('d-m-Y h:i a', strtotime($value['date_time']));
- // Initialize buttons
$buttons = '';
- if (in_array('viewOrder', $this->permission)) {
+ // Bouton imprimer (sauf pour SECURITE)
+ if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") {
$buttons .= '';
}
-
+
if (in_array('updateOrder', $this->permission) && $users["id"] == $value['user_id']) {
- $buttons .= ' ';
+
+ $buttons .= ' ';
+
}
+
if (in_array('viewOrder', $this->permission)) {
$buttons .= '
';
}
-
if (in_array('deleteOrder', $this->permission) && $users["id"] == $value['user_id']) {
$buttons .= ' ';
}
- // Paid status label
- $paid_status = ($value['paid_status'] == 1)
- ? 'Payé'
- : 'Non payé';
+
+ // Statut de paiement
+ if ($value['paid_status'] == 1) {
+ $paid_status = 'Validé';
+ } elseif ($value['paid_status'] == 2) {
+ $paid_status = 'En Attente';
+ } elseif ($value['paid_status'] == 3) {
+ $paid_status = 'Validé et Livré';
+ } else {
+ $paid_status = 'Refusé';
+ }
+ // Calcul délai (SANS notification)
$date1 = new DateTime($date_time);
- $date2 = new DateTime(); // Current date and time
-
- // Calculate the difference in days
+ $date2 = new DateTime();
$interval = $date1->diff($date2);
$daysPassed = $interval->days;
- $statuDate = '';
- // die(var_dump($daysPassed));
- $Notification = new NotificationController();
- // die(var_dump($_SERVER['REQUEST_URI'] == "/orders/fetchOrdersData"));
- $uri = $_SERVER['REQUEST_URI'];
- if ($daysPassed < 8 && $value['paid_status'] == 2) {
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
- } else if ($daysPassed >= 8 && $value['paid_status'] == 2) {
- $Notification->createNotification("Conseil : Confirmation de reservation", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
- } else if ($daysPassed >= 15 && $value['paid_status'] == 2) {
- $Notification->createNotification("Conseil : Reservation expiré", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
- $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ $statuDate = '';
+ if ($value['paid_status'] == 2) {
+ if ($daysPassed < 8) {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ } elseif ($daysPassed >= 8 && $daysPassed < 15) {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ } else {
+ $statuDate = ' depuis ' . $daysPassed . ' Jours';
+ }
}
- $Orders_items= new OrderItems();
- $sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
- // Add data to the result array
+ // $Orders_items= new OrderItems();
+ // $sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
+
$result['data'][$key] = [
$value['product_names'],
$value['user_name'],
$date_time . "
" . $statuDate,
- $sum_order_item,
- number_format((int) $value['net_amount'], 0, ',', ' '),
+ number_format((int) $value['discount'], 0, ',', ' '),
+ number_format((int) $value['gross_amount'], 0, ',', ' '),
$paid_status,
$buttons
];
}
return $this->response->setJSON($result);
}
- }
- // Return JSON response
-
}
+ /**
+ * Affiche le formulaire create avec les données d'une commande existante
+ * Pour le rôle COMMERCIALE
+ */
+
/**
* function who check if the product is null
* and create notification about it
@@ -273,7 +285,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", "Conseil", $store_id, "products");
+ $notification->createNotification("Produit en rupture de stock", "Direction", $store_id, "products");
}
}
}
@@ -285,52 +297,95 @@ class OrderController extends AdminController
for ($i = 0; $i < \count($amount); $i++) {
$montant += $amount[$i];
}
-
return $montant;
}
+
+
public function create()
{
$this->verifyRole('createOrder');
$data['page_title'] = $this->pageTitle;
-
- // Load validation service
+
$validation = \Config\Services::validation();
-
- // echo '
';
- // die(var_dump($this->request->getPost('product[]')));
-
$products = $this->request->getPost('product[]');
-
- // Then, manually check for uniqueness
+
if ($products !== null && (count($products) !== count(array_unique($products)))) {
return redirect()->back()->withInput()->with('errors', ['product' => 'Chaque produit sélectionné doit être unique.']);
}
-
- // Set validation rules
+
$validation->setRules([
'product[]' => 'required'
]);
- // echo '';
- // die(var_dump($this->request->getPost()));
-
+
$validationData = [
'product[]' => $this->request->getPost('product[]')
];
-
+
$Orders = new Orders();
$Company = new Company();
$Products = new Products();
-
+
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
-
+
$session = session();
$users = $session->get('user');
$user_id = $users['id'];
$bill_no = 'BILPR-' . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 4));
-
- // If validation passes
-
+
+ // Récupération des produits
+ $posts = $this->request->getPost('product[]');
+ $rates = $this->request->getPost('rate_value[]');
+ $amounts = $this->request->getPost('amount_value[]');
+ $discount = (float)$this->request->getPost('discount') ?? 0;
+ $gross_amount = $this->calculGross($amounts);
+
+ // ✅ Vérification prix minimal SI rabais existe
+ if ($discount > 0) {
+ $FourchettePrix = new \App\Models\FourchettePrix();
+
+ foreach ($posts as $index => $productId) {
+ $productId = (int)$productId;
+
+ // Récupérer données produit + prix minimal
+ $productData = $Products->getProductData($productId);
+ $fourchette = $FourchettePrix->getFourchettePrixByProductId($productId);
+
+ if ($fourchette) {
+ $prixMinimal = (float)$fourchette['prix_minimal'];
+
+ // ✅ Le rabais devient le prix de vente
+ if ($discount < $prixMinimal) {
+ $prixMinimalFormatted = number_format($prixMinimal, 0, ',', ' ');
+ $discountFormatted = number_format($discount, 0, ',', ' ');
+
+ return redirect()->back()
+ ->withInput()
+ ->with('errors', [
+ "⚠️ Commande bloquée : Le rabais de {$discountFormatted} Ar pour « {$productData['name']} » est inférieur au prix minimal autorisé de {$prixMinimalFormatted} Ar."
+ ]);
+ }
+ }
+ }
+ }
+
+ // ✅ NOUVELLE LOGIQUE : Calculer le montant à payer et net_amount
+ $montant_a_payer = ($discount > 0) ? $discount : $gross_amount;
+
+ // Récupérer les tranches
+ $tranche_1 = (float)$this->request->getPost('tranche_1') ?? 0;
+ $tranche_2 = (float)$this->request->getPost('tranche_2') ?? 0;
+
+ // Calculer net_amount selon les tranches
+ if ($tranche_1 > 0 && $tranche_2 > 0) {
+ // Paiement en 2 tranches
+ $net_amount = $tranche_1 + $tranche_2;
+ } else {
+ // Paiement en 1 tranche ou pas de tranches
+ $net_amount = $montant_a_payer;
+ }
+
+ // ✅ Création de la commande avec la nouvelle logique
$data = [
'bill_no' => $bill_no,
'customer_name' => $this->request->getPost('customer_name'),
@@ -338,97 +393,109 @@ class OrderController extends AdminController
'customer_phone' => $this->request->getPost('customer_phone'),
'customer_cin' => $this->request->getPost('customer_cin'),
'date_time' => date('Y-m-d H:i:s'),
- 'service_charge_rate' => $this->request->getPost('service_charge_rate'),
- 'vat_charge_rate' => $this->request->getPost('vat_charge_rate'),
- 'vat_charge' => ($this->request->getPost('vat_charge_value') > 0) ? $this->request->getPost('vat_charge_value') : 0,
- 'net_amount' => $this->request->getPost('net_amount'),
- 'discount' => $this->request->getPost('discount'),
- 'paid_status' => 2,
+ 'service_charge_rate' => 0,
+ 'vat_charge_rate' => 0,
+ 'vat_charge' => 0,
+ 'net_amount' => $net_amount, // ✅ Net amount = tranches OU montant_a_payer
+ 'discount' => $discount,
+ 'paid_status' => 2, // Toujours En Attente au départ
'user_id' => $user_id,
- // 'qty' => $this->request->getPost('qty[]'),
- 'amount_value' => $this->request->getPost('amount_value[]'),
- 'gross_amount' => $this->calculGross($this->request->getPost('amount_value[]')),
- 'rate_value' => $this->request->getPost('rate_value[]'),
+ 'amount_value' => $amounts,
+ 'gross_amount' => $gross_amount,
+ 'rate_value' => $rates,
'store_id' => $users['store_id'],
+ 'tranche_1' => $tranche_1,
+ 'tranche_2' => $tranche_2,
+ 'order_payment_mode' => $this->request->getPost('order_payment_mode_1'),
+ 'order_payment_mode_1' => $this->request->getPost('order_payment_mode_2')
];
-
- $posts = $this->request->getPost('product[]');
-
- // echo '';
- // die(var_dump($data));
+
$order_id = $Orders->create($data, $posts);
- $Order_item1 = new OrderItems();
- $order_item_data = $Order_item1->getOrdersItemData($order_id);
- $product_ids = array_column($order_item_data, 'product_id');
-
- $Notification = new NotificationController();
-
- if ((int) (int) $this->request->getPost('discount') > 0) {
- $productData = new Products();
- $product_data_results = [];
-
- foreach ($product_ids as $prod_id) {
-
- $id = (int) $prod_id;
-
- // Appel de la méthode pour chaque ID
- $product_data_results[] = $productData->getProductData($id);
- }
-
- $product_lines = [];
-
- foreach ($product_data_results as $product) {
- if (isset($product['sku'], $product['price'])) {
- $sku = $product['sku'];
- $price = $product['price'];
- $product_lines[] = "{$sku}:{$price}";
- }
- }
-
- $product_output = implode("\n", $product_lines);
-
-
- // data for the remise
- $data1 = [
- 'date_demande' => date('Y-m-d H:i:s'),
- 'montant_demande' => $this->request->getPost('discount'),
- 'total_price' => $this->request->getPost('amount_value[]'),
- 'id_store' => $users['store_id'],
- 'id_order' => $order_id,
- 'product' => $product_output,
- 'demande_status' => 'En attente'
- ];
-
- $Remise = new Remise();
- $id_remise = $Remise->addDemande($data1);
- $Notification->createNotification("Un nouveau demande de remise été ajouté", "Conseil", (int)$users['store_id'], 'remise');
- }
-
+
if ($order_id) {
session()->setFlashdata('success', 'Créé avec succès');
- $Notification->createNotification("Un nouveau commade ajouter", "Caissière", (int)$users['store_id'], "orders");
+
+ $Notification = new NotificationController();
+
+ // ✅ WORKFLOW SELON LA REMISE
+ if ($discount > 0) {
+ // AVEC REMISE : Créer demande + Notifier Conseil
+ $Order_item1 = new OrderItems();
+ $order_item_data = $Order_item1->getOrdersItemData($order_id);
+ $product_ids = array_column($order_item_data, 'product_id');
+
+ $productData = new Products();
+ $product_data_results = [];
+
+ foreach ($product_ids as $prod_id) {
+ $id = (int) $prod_id;
+ $product_data_results[] = $productData->getProductData($id);
+ }
+
+ $product_lines = [];
+ foreach ($product_data_results as $product) {
+ if (isset($product['sku'], $product['price'])) {
+ $sku = $product['sku'];
+ $price = $product['price'];
+ $product_lines[] = "{$sku}:{$price}";
+ }
+ }
+
+ $product_output = implode("\n", $product_lines);
+
+ $data1 = [
+ 'date_demande' => date('Y-m-d H:i:s'),
+ 'montant_demande' => $discount,
+ 'total_price' => $amounts,
+ 'id_store' => $users['store_id'],
+ 'id_order' => $order_id,
+ 'product' => $product_output,
+ 'demande_status' => 'En attente'
+ ];
+
+ $Remise = new Remise();
+ $id_remise = $Remise->addDemande($data1);
+
+ // Notification au CONSEIL
+ $Notification->createNotification(
+ "Nouvelle demande de remise à valider - Commande " . $bill_no,
+ "Direction",
+ (int)$users['store_id'],
+ "remise/"
+ );
+
+ } else {
+ // SANS REMISE : Notifier directement la Caissière
+ $Notification->createNotification(
+ "Nouvelle commande à valider - " . $bill_no,
+ "Caissière",
+ (int)$users['store_id'],
+ "orders"
+ );
+ }
+
+ // Redirection selon le rôle
if ($users["group_name"] != "COMMERCIALE") {
-
$this->checkProductisNull($posts, $users['store_id']);
-
return redirect()->to('orders/update/' . $order_id);
} else {
-
return redirect()->to('orders/');
}
+
} else {
session()->setFlashdata('errors', 'Error occurred!!');
return redirect()->to('orders/create/');
}
+
} else {
- // If validation fails
+ // Affichage du formulaire
$company = $Company->getCompanyData(1);
-
$session = session();
$users = $session->get('user');
$store_id = $users['store_id'];
- // Prepare data for the view
+
$data = [
+ 'paid_status' => 2,
'company_data' => $company,
'is_vat_enabled' => ($company['vat_charge_value'] > 0),
'is_service_enabled' => ($company['service_charge_value'] > 0),
@@ -436,23 +503,111 @@ class OrderController extends AdminController
'validation' => $validation,
'page_title' => $this->pageTitle,
];
-
- // Render the view with the prepared data
+
return $this->render_template('orders/create', $data);
}
}
+
+/**
+ * Marquer une commande comme livrée
+ * Accessible uniquement par le rôle SECURITE
+ */
+public function markAsDelivered()
+{
+ // Activer le retour JSON même en cas d'erreur
+ ini_set('display_errors', 0);
+
+ $order_id = $this->request->getPost('order_id');
+ $response = ['success' => false, 'messages' => ''];
+
+ try {
+ $session = session();
+ $users = $session->get('user');
+
+ // Vérifier que l'utilisateur est SECURITE
+ if (!isset($users['group_name']) || $users['group_name'] !== 'SECURITE') {
+ $response['messages'] = "Accès refusé : seule la sécurité peut marquer une commande comme livrée.";
+ return $this->response->setJSON($response);
+ }
+
+ if (!$order_id) {
+ $response['messages'] = "ID de commande manquant.";
+ return $this->response->setJSON($response);
+ }
+
+ $Orders = new Orders();
+
+ // Récupérer la commande actuelle
+ $current_order = $Orders->getOrdersData((int)$order_id);
+
+ if (!$current_order) {
+ $response['messages'] = "Commande introuvable.";
+ return $this->response->setJSON($response);
+ }
+
+ // Vérifier que la commande est validée (paid_status = 1)
+ if ($current_order['paid_status'] != 1) {
+ $response['messages'] = "Cette commande doit être validée avant d'être marquée comme livrée.";
+ return $this->response->setJSON($response);
+ }
+
+ // Mettre à jour UNIQUEMENT le statut à 3 (Livré)
+ $updated = $Orders->update((int)$order_id, ['paid_status' => 3]);
+
+ if ($updated) {
+ // Créer une notification
+ try {
+ $Notification = new NotificationController();
+ $Notification->createNotification(
+ "Commande " . $current_order['bill_no'] . " livrée avec succès",
+ "Direction",
+ (int)$current_order['store_id'],
+ "orders"
+ );
+ } catch (\Exception $e) {
+ // Si la notification échoue, on continue quand même
+ log_message('error', 'Erreur notification: ' . $e->getMessage());
+ }
+
+ $response['success'] = true;
+ $response['messages'] = "La commande a été marquée comme livrée avec succès.";
+ } else {
+ $response['messages'] = "Erreur lors de la mise à jour du statut.";
+ }
+
+ } catch (\Exception $e) {
+ log_message('error', 'Erreur markAsDelivered: ' . $e->getMessage());
+ $response['messages'] = "Erreur serveur : " . $e->getMessage();
+ }
+
+ return $this->response->setJSON($response);
+}
+
public function getProductValueById()
{
$product_id = $this->request->getPost('product_id');
if ($product_id) {
- $Products = new Products();
+ $Products = new \App\Models\Products();
$product_data = $Products->getProductData($product_id);
- return $this->response->setJSON($product_data);
+
+ $FourchettePrix = new \App\Models\FourchettePrix();
+ $fourchette = $FourchettePrix->where('product_id', $product_id)->first();
+
+ $response = [
+ 'id' => $product_data['id'],
+ 'sku' => $product_data['sku'],
+ 'name' => $product_data['name'],
+ 'prix_vente' => $product_data['prix_vente'],
+ 'prix_minimal' => $fourchette ? $fourchette['prix_minimal'] : 0,
+ ];
+
+ return $this->response->setJSON($response);
}
}
+
- public function getTableProductRow()
+ public function getTableProductRow()
{
$Products = new Products();
$session = session();
@@ -464,7 +619,6 @@ class OrderController extends AdminController
return $this->response->setJSON($product_data);
}
-
public function update(int $id)
{
$this->verifyRole('updateOrder');
@@ -472,7 +626,7 @@ class OrderController extends AdminController
$data['page_title'] = $this->pageTitle;
$validation = \Config\Services::validation();
- // Définir les règles de validation
+ // Règles de validation
$validation->setRules([
'product' => 'required'
]);
@@ -486,7 +640,29 @@ class OrderController extends AdminController
$Products = new Products();
$OrderItems = new OrderItems();
+ $session = session();
+ $user = $session->get('user');
+ $role = $user['group_name'] ?? null;
+
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
+
+ $current_order = $Orders->getOrdersData($id);
+ $old_paid_status = $current_order['paid_status'];
+
+ // ✅ Statut payé pour COMMERCIALE reste toujours "En attente"
+ if ($role === 'COMMERCIALE') {
+ $paid_status = 2; // ← mettre la valeur correspondant à "En attente" dans votre table
+ } else {
+ $paid_status = $this->request->getPost('paid_status');
+ }
+
+ // Gestion remise
+ $discount = $this->request->getPost('discount');
+ $original_discount = $this->request->getPost('original_discount');
+ if ($discount === '' || $discount === null) {
+ $discount = $original_discount;
+ }
+
$dataUpdate = [
'customer_name' => $this->request->getPost('customer_name'),
'customer_address' => $this->request->getPost('customer_address'),
@@ -498,16 +674,16 @@ class OrderController extends AdminController
'vat_charge_rate' => $this->request->getPost('vat_charge_rate'),
'vat_charge' => max(0, (float)$this->request->getPost('vat_charge_value')),
'net_amount' => $this->request->getPost('net_amount_value'),
- 'discount' => $this->request->getPost('discount'),
- 'paid_status' => $this->request->getPost('paid_status'),
+ 'discount' => (float)$discount,
+ 'paid_status' => $paid_status,
'product' => $this->request->getPost('product'),
'product_sold' => true,
'rate_value' => $this->request->getPost('rate_value'),
'amount_value' => $this->request->getPost('amount_value'),
- 'tranche_1' => $this->request->getPost('tranche_1'),
- 'tranche_2' => $this->request->getPost('tranche_2'),
- 'order_payment_mode' => $this->request->getPost('order_payment_mode_1'),
- 'order_payment_mode_1' => $this->request->getPost('order_payment_mode_2')
+ 'tranche_1' => $role !== 'COMMERCIALE' ? $this->request->getPost('tranche_1') : null,
+ 'tranche_2' => $role !== 'COMMERCIALE' ? $this->request->getPost('tranche_2') : null,
+ 'order_payment_mode' => $role !== 'COMMERCIALE' ? $this->request->getPost('order_payment_mode_1') : null,
+ 'order_payment_mode_1' => $role !== 'COMMERCIALE' ? $this->request->getPost('order_payment_mode_2') : null
];
if ($Orders->updates($id, $dataUpdate)) {
@@ -516,9 +692,21 @@ class OrderController extends AdminController
$Notification = new NotificationController();
- $discount = (int) $this->request->getPost('discount');
+ // Notification pour la sécurité si commande validée
+ if ($old_paid_status == 2 && $paid_status == 1) {
+ $customer_name = $this->request->getPost('customer_name');
+ $bill_no = $current_order['bill_no'];
- if ($discount > 0) {
+ $Notification->createNotification(
+ "Commande validée: {$bill_no} - Client: {$customer_name}",
+ "SECURITE",
+ (int)$user['store_id'],
+ 'orders'
+ );
+ }
+
+ // Gestion demande de remise
+ if ((float)$discount > 0) {
$productData = new Products();
$product_data_results = [];
@@ -535,22 +723,25 @@ class OrderController extends AdminController
$product_output = implode("\n", $product_lines);
- $session = session();
- $users = $session->get('user');
-
$data1 = [
'date_demande' => date('Y-m-d H:i:s'),
'montant_demande' => $this->request->getPost('discount'),
'total_price' => $this->request->getPost('amount_value'),
- 'id_store' => $users['store_id'],
+ 'id_store' => $user['store_id'],
'id_order' => $id,
'product' => $product_output,
'demande_status' => 'En attente'
];
$Remise = new Remise();
- $Remise->updateRemise1($id,$data1);
- $Notification->createNotification("Un nouveau demande de remise a été ajouté", "Conseil", (int)$users['store_id'] ?? null, 'remise');
+ $Remise->updateRemise1($id, $data1);
+
+ $Notification->createNotification(
+ "Une nouvelle demande de remise a été ajoutée",
+ "Direction",
+ (int)$user['store_id'] ?? null,
+ "remise/"
+ );
}
session()->setFlashData('success', 'Commande mise à jour avec succès.');
@@ -561,13 +752,19 @@ class OrderController extends AdminController
}
}
- // En cas d’échec de la validation ou si GET
+ // Si GET ou validation échoue
$company = $Company->getCompanyData(1);
$data['company_data'] = $company;
$data['is_vat_enabled'] = ($company['vat_charge_value'] > 0);
$data['is_service_enabled'] = ($company['service_charge_value'] > 0);
$orders_data = $Orders->getOrdersData($id);
+
+ // Montant tranches
+ $orders_data['montant_tranches'] = (!empty($orders_data['discount']) && $orders_data['discount'] > 0)
+ ? $orders_data['discount']
+ : $orders_data['gross_amount'];
+
$result = ['order' => $orders_data];
$orders_item = $OrderItems->getOrdersItemData($orders_data['id']);
@@ -594,6 +791,7 @@ class OrderController extends AdminController
$Company = new Company();
$Products = new Products();
$OrderItems = new OrderItems();
+ $Brands = new Brands();
// En cas d’échec de la validation ou si GET
$company = $Company->getCompanyData(1);
@@ -602,10 +800,10 @@ class OrderController extends AdminController
$data['is_service_enabled'] = ($company['service_charge_value'] > 0);
$orders_data = $Orders->getOrdersData($id);
- $sum_order_item = $OrderItems->getSumOrdersItemData($orders_data['id']);
+ // $sum_order_item = $OrderItems->getSumOrdersItemData($orders_data['id']);
$result = [
'order' => $orders_data,
- 'sum_order_data' => $sum_order_item
+ // 'sum_order_data' => $sum_order_item
];
$orders_item = $OrderItems->getOrdersItemData($orders_data['id']);
@@ -616,6 +814,7 @@ class OrderController extends AdminController
$data['order_data'] = $result;
$data['products'] = $Products->getActiveProductData();
+ $data['brands'] = $Brands->findAll();
return $this->response->setJSON($data);
@@ -659,7 +858,13 @@ class OrderController extends AdminController
$html = '';
// Vérifier si l'utilisateur a payé
- $paid_status = ($order_data['paid_status'] == 1) ? "Payé" : "Non payé";
+ if ($order_data['paid_status'] == 1) {
+ $paid_status = "Validé";
+ } elseif ($order_data['paid_status'] == 2) {
+ $paid_status = "En Attente";
+ } else {
+ $paid_status = "Refusé";
+ }
// Génération du HTML
$html .= '
@@ -1093,7 +1298,7 @@ class OrderController extends AdminController
'is_vat_enabled' => ($company['vat_charge_value'] > 0),
'is_service_enabled' => ($company['service_charge_value'] > 0),
'products' => $Products->getProductData($id),
- 'totalqtt' => $Products->getProductData($id)['qty'],
+ // 'discount' => $Products->getProductData($id)['discount'],
'pu' => $Products->getProductData($id)['prix_vente'],
'page_title' => $this->pageTitle,
];
@@ -1328,6 +1533,8 @@ public function print3(int $id)
echo'