diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index cb3cd98b..064f6389 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -174,11 +174,11 @@ $routes->group('', ['filter' => 'auth'], function ($routes) {
$routes->get('update/(:num)', [ProductCOntroller::class, 'update']);
$routes->post('update/(:num)', [ProductCOntroller::class, 'update']);
$routes->post('remove', [ProductCOntroller::class, 'remove']);
- // $routes->get('generateqrcode/(:num)', [QrCodeController::class, 'generate']);
$routes->post('assign_store', [ProductCOntroller::class, 'assign_store']);
$routes->post('createByExcel', [ProductCOntroller::class, 'createByExcel']);
-
+ $routes->post('checkProductAvailability', [ProductCOntroller::class, 'checkProductAvailability']);
});
+
/**
* route for the orders
@@ -296,10 +296,12 @@ $routes->group('/sortieCaisse', function ($routes) {
});
// avance
+// ✅ DANS app/Config/Routes.php
+
$routes->group('/avances', function ($routes) {
$routes->get('/', [AvanceController::class, 'index']);
- // ✅ Routes pour récupérer les données (GET)
+ // Routes pour récupérer les données (GET)
$routes->get('fetchAvanceData', [AvanceController::class, 'fetchAvanceData']);
$routes->get('fetchAvanceBecameOrder', [AvanceController::class, 'fetchAvanceBecameOrder']);
$routes->get('fetchExpiredAvance', [AvanceController::class, 'fetchExpiredAvance']);
@@ -310,22 +312,27 @@ $routes->group('/avances', function ($routes) {
$routes->get('getFullInvoiceForPrint/(:num)', [AvanceController::class, 'getFullInvoiceForPrint/$1']);
$routes->get('printInvoice/(:num)', [AvanceController::class, 'printInvoice/$1']);
- // ✅ Routes POST pour modifications
+ // Routes POST pour modifications
$routes->post('createAvance', [AvanceController::class, 'createAvance']);
$routes->post('updateAvance', [AvanceController::class, 'updateAvance']);
$routes->post('deleteAvance', [AvanceController::class, 'removeAvance']);
$routes->post('notifyPrintInvoice', [AvanceController::class, 'notifyPrintInvoice']);
-
- // ✅ AJOUTER CETTE ROUTE MANQUANTE
$routes->post('processExpiredAvances', [AvanceController::class, 'processExpiredAvances']);
- // ✅ Route CRON (optionnel)
+ // ✅ CORRECTION : Routes pour paiement et conversion
+ $routes->post('payAvance', [AvanceController::class, 'payAvance']);
+
+ // ✅ AJOUT : Routes GET ET POST pour la conversion manuelle
+ $routes->get('checkAndConvertCompleted', [AvanceController::class, 'checkAndConvertCompleted']);
+ $routes->post('checkAndConvertCompleted', [AvanceController::class, 'checkAndConvertCompleted']);
+
+ // Route pour forcer la conversion d'une avance spécifique
+ $routes->get('forceConvertToOrder/(:num)', [AvanceController::class, 'forceConvertToOrder/$1']);
+
+ // Route CRON (optionnel)
$routes->get('checkDeadlineAlerts', [AvanceController::class, 'checkDeadlineAlerts']);
-
- $routes->post('payAvance', 'AvanceController::payAvance');
- $routes->get('forceConvertToOrder/(:num)', 'AvanceController::forceConvertToOrder/$1');
- $routes->post('checkAndConvertCompleted', 'AvanceController::checkAndConvertCompleted');
});
+
// historique
$routes->group('historique', ['filter' => 'auth'], static function ($routes) {
$routes->get('/', 'HistoriqueController::index');
diff --git a/app/Controllers/AvanceController.php b/app/Controllers/AvanceController.php
index f09b1181..7579badd 100644
--- a/app/Controllers/AvanceController.php
+++ b/app/Controllers/AvanceController.php
@@ -2114,6 +2114,13 @@ public function payAvance()
$avance_id = $this->request->getPost('avance_id');
$montant_paye = (float)$this->request->getPost('montant_paye');
+ if (!$avance_id || $montant_paye <= 0) {
+ return $this->response->setJSON([
+ 'success' => false,
+ 'message' => 'Données invalides'
+ ]);
+ }
+
$avanceModel = new \App\Models\Avance();
$avance = $avanceModel->find($avance_id);
@@ -2124,52 +2131,62 @@ public function payAvance()
]);
}
- // Calcul du nouveau montant dû
+ // ✅ Vérifier si déjà convertie
+ if ($avance['is_order'] == 1) {
+ return $this->response->setJSON([
+ 'success' => false,
+ 'message' => '⚠️ Cette avance a déjà été convertie en commande'
+ ]);
+ }
+
+ // ✅ Calcul nouveau montant dû
$amount_due = max(0, (float)$avance['amount_due'] - $montant_paye);
- // ✅ Mise à jour de l'avance
+ // ✅ Mise à jour avance
$avanceModel->update($avance_id, [
'avance_amount' => (float)$avance['avance_amount'] + $montant_paye,
'amount_due' => $amount_due,
]);
- // ✅ NOUVEAU : Conversion automatique UNIQUEMENT pour avances TERRE
+ log_message('info', "💰 Paiement {$montant_paye} Ar sur avance {$avance_id} (Type: {$avance['type_avance']})");
+
+ // ✅ CONVERSION si paiement complet
if ($amount_due <= 0) {
if ($avance['type_avance'] === 'terre') {
- // ✅ Avance TERRE complète → Conversion en commande
- log_message('info', "💰 Avance TERRE {$avance_id} complétée ! Conversion en commande...");
+ log_message('info', "🔄 Avance TERRE {$avance_id} complétée → Conversion en commande...");
$order_id = $avanceModel->convertToOrder($avance_id);
if ($order_id) {
+ log_message('info', "✅ Conversion réussie → Commande {$order_id}");
+
return $this->response->setJSON([
'success' => true,
- 'message' => '✅ Paiement effectué ! L\'avance TERRE a été convertie en commande.',
+ 'message' => '✅ Paiement effectué ! L\'avance a été convertie en commande.',
'converted' => true,
'type' => 'terre',
'order_id' => $order_id,
'redirect_url' => site_url('orders/update/' . $order_id)
]);
} else {
- log_message('error', "Échec conversion avance TERRE {$avance_id} en commande");
+ log_message('error', "❌ Échec conversion avance {$avance_id}");
+
return $this->response->setJSON([
- 'success' => true,
- 'message' => '⚠️ Paiement effectué mais erreur lors de la création de la commande.',
- 'converted' => false
+ 'success' => false,
+ 'message' => '⚠️ Paiement enregistré mais erreur lors de la conversion. Contactez l\'administrateur.'
]);
}
} else {
- // ✅ Avance MER complète → Reste dans la liste
- log_message('info', "💰 Avance MER {$avance_id} complétée ! Elle reste dans la liste des avances.");
+ // ✅ Avance MER complète
+ log_message('info', "✅ Avance MER {$avance_id} complétée (pas de conversion)");
return $this->response->setJSON([
'success' => true,
'message' => '✅ Paiement effectué ! L\'avance MER est maintenant complète.',
'converted' => false,
- 'type' => 'mere',
- 'status' => 'completed'
+ 'type' => 'mere'
]);
}
}
@@ -2177,8 +2194,9 @@ public function payAvance()
// ✅ Paiement partiel
return $this->response->setJSON([
'success' => true,
- 'message' => '✅ Paiement partiel enregistré avec succès',
+ 'message' => '✅ Paiement partiel enregistré',
'amount_due_remaining' => $amount_due,
+ 'amount_due_formatted' => number_format($amount_due, 0, ',', ' ') . ' Ar',
'type' => $avance['type_avance']
]);
}
@@ -2187,16 +2205,33 @@ public function payAvance()
*/
public function forceConvertToOrder($avance_id)
{
- $this->verifyRole('updateAvance'); // Adapter selon vos permissions
+ $this->verifyRole('updateAvance');
$avanceModel = new \App\Models\Avance();
+ $avance = $avanceModel->find($avance_id);
+
+ if (!$avance) {
+ session()->setFlashdata('errors', 'Avance introuvable');
+ return redirect()->back();
+ }
+
+ if ($avance['type_avance'] !== 'terre') {
+ session()->setFlashdata('errors', 'Seules les avances TERRE peuvent être converties');
+ return redirect()->back();
+ }
+
+ if ($avance['amount_due'] > 0) {
+ session()->setFlashdata('errors', 'L\'avance doit être complètement payée avant conversion');
+ return redirect()->back();
+ }
+
$order_id = $avanceModel->convertToOrder($avance_id);
if ($order_id) {
session()->setFlashdata('success', 'Avance convertie en commande avec succès !');
return redirect()->to('orders/update/' . $order_id);
} else {
- session()->setFlashdata('errors', 'Erreur lors de la conversion de l\'avance.');
+ session()->setFlashdata('errors', 'Erreur lors de la conversion');
return redirect()->back();
}
}
@@ -2208,16 +2243,33 @@ public function forceConvertToOrder($avance_id)
public function checkAndConvertCompleted()
{
try {
- $Avance = new Avance();
+ log_message('info', "=== DÉBUT checkAndConvertCompleted (manuel) ===");
- // ✅ Récupérer uniquement les avances TERRE complètes non converties
- $completedTerreAvances = $Avance->getCompletedNotConverted();
+ $Avance = new \App\Models\Avance();
+
+ // ✅ Récupérer toutes les avances TERRE complètes non converties
+ $completedTerreAvances = $Avance
+ ->where('type_avance', 'terre')
+ ->where('amount_due <=', 0)
+ ->where('is_order', 0)
+ ->where('active', 1)
+ ->findAll();
+
+ if (empty($completedTerreAvances)) {
+ return $this->response->setJSON([
+ 'success' => true,
+ 'message' => 'Aucune avance complète à convertir',
+ 'converted' => 0
+ ]);
+ }
$convertedCount = 0;
$errorCount = 0;
$details = [];
foreach ($completedTerreAvances as $avance) {
+ log_message('info', "🔍 Traitement avance {$avance['avance_id']}...");
+
$order_id = $Avance->convertToOrder($avance['avance_id']);
if ($order_id) {
@@ -2225,32 +2277,35 @@ public function checkAndConvertCompleted()
$details[] = [
'avance_id' => $avance['avance_id'],
'customer' => $avance['customer_name'],
- 'type' => 'terre',
'order_id' => $order_id,
'status' => 'success'
];
+ log_message('info', "✅ Avance {$avance['avance_id']} → Commande {$order_id}");
} else {
$errorCount++;
$details[] = [
'avance_id' => $avance['avance_id'],
'customer' => $avance['customer_name'],
- 'type' => 'terre',
- 'status' => 'error'
+ 'status' => 'error',
+ 'reason' => 'Voir logs pour détails'
];
+ log_message('error', "❌ Échec conversion avance {$avance['avance_id']}");
}
}
+ log_message('info', "=== FIN checkAndConvertCompleted - Convertis: {$convertedCount}, Erreurs: {$errorCount} ===");
+
return $this->response->setJSON([
'success' => true,
'message' => 'Vérification terminée',
'converted' => $convertedCount,
'errors' => $errorCount,
- 'note' => 'Seules les avances TERRE sont converties. Les avances MER restent dans la liste.',
+ 'total_checked' => count($completedTerreAvances),
'details' => $details
]);
} catch (\Exception $e) {
- log_message('error', "Erreur checkAndConvertCompleted: " . $e->getMessage());
+ log_message('error', "❌ Erreur checkAndConvertCompleted: " . $e->getMessage());
return $this->response->setJSON([
'success' => false,
'messages' => 'Erreur: ' . $e->getMessage()
@@ -2258,4 +2313,5 @@ public function checkAndConvertCompleted()
}
}
+
}
\ No newline at end of file
diff --git a/app/Controllers/OrderController.php b/app/Controllers/OrderController.php
index 8015e0d1..bd10ea07 100644
--- a/app/Controllers/OrderController.php
+++ b/app/Controllers/OrderController.php
@@ -41,26 +41,46 @@ class OrderController extends AdminController
* @param int $store_id
* @return string
*/
- private function generateBillNo(int $store_id): string
+ private function generateSimpleSequentialBillNo(int $store_id): string
{
- // Mapping des préfixes par magasin
$storePrefixes = [
- 1 => 'ANTS', // ANTSAKAVIRO
- 2 => 'BESA', // BESARETY
- 3 => 'BYPA', // BYPASS
- 4 => 'TOAM', // TOAMASINA
+ 1 => 'ANTS',
+ 2 => 'BESA',
+ 3 => 'BYPA',
+ 4 => 'TOAM',
];
-
- // Récupérer le préfixe du magasin, ou utiliser un préfixe par défaut
- $prefix = $storePrefixes[$store_id] ?? 'BILPR';
-
- // Générer un identifiant unique
- $uniqueId = strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 6));
-
- // Retourner le numéro de facture formaté
- return $prefix . '-' . $uniqueId;
+
+ $prefix = $storePrefixes[$store_id] ?? 'STORE';
+
+ $db = \Config\Database::connect();
+
+ $lastBill = $db->table('orders')
+ ->select('bill_no')
+ ->like('bill_no', $prefix . '-', 'after')
+ ->orderBy('id', 'DESC')
+ ->limit(1)
+ ->get()
+ ->getRowArray();
+
+ if ($lastBill && !empty($lastBill['bill_no'])) {
+ // Extraire le numéro (ex: "BESA-001" -> 1)
+ preg_match('/-(\d+)$/', $lastBill['bill_no'], $matches);
+
+ if (isset($matches[1])) {
+ $lastNumber = (int)$matches[1];
+ $newNumber = $lastNumber + 1;
+ } else {
+ $newNumber = 1;
+ }
+ } else {
+ $newNumber = 1;
+ }
+
+ // Formater avec zéros (ex: 001, 002, 010, 100)
+ return $prefix . '-' . str_pad($newNumber, 3, '0', STR_PAD_LEFT);
}
+
public function fetchOrdersData()
{
helper(['url', 'form']);
@@ -75,53 +95,102 @@ class OrderController extends AdminController
// POUR CAISSIÈRE
// ========================================
if ($users['group_name'] == "Caissière") {
+ $Remise = new Remise();
+
foreach ($data as $key => $value) {
$date_time = date('d-m-Y h:i a', strtotime($value['date_time']));
-
+
$buttons = '';
-
- // 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 pour statuts 0 (Refusé) et 2 (En Attente)
- if (in_array('updateOrder', $this->permission)
- && $users["store_id"] == $value['store_id']
- && in_array($value['paid_status'], [0, 2])) {
- $buttons .= ' ';
+ $discount = (float)$value['discount'];
+
+ // ✅ VÉRIFICATION : Si la commande est refusée (paid_status = 0), aucun bouton
+ if ($value['paid_status'] == 0) {
+ $buttons = ' Accès bloqué';
+ } else {
+ // ✅ Bouton imprimer
+ if (in_array('viewOrder', $this->permission)) {
+ // CAS 1 : Commande payée (1) ou livrée (3) → Toujours afficher imprimer
+ if (in_array($value['paid_status'], [1, 3])) {
+ $buttons .= '';
+ }
+ // CAS 2 : Commande en attente (2) SANS remise → Afficher imprimer
+ elseif ($value['paid_status'] == 2 && $discount == 0) {
+ $buttons .= '';
+ }
+ // CAS 3 : Commande en attente (2) AVEC remise validée → Afficher imprimer
+ elseif ($value['paid_status'] == 2 && $Remise->hasRemiseValidatedForOrder($value['id'])) {
+ $buttons .= '';
+ }
+ // CAS 4 : Commande en attente (2) AVEC remise en attente → Indicateur
+ elseif ($value['paid_status'] == 2 && $Remise->hasRemisePendingForOrder($value['id'])) {
+ $buttons .= '';
+ }
+ }
+
+ // ✅ Bouton voir
+ if (in_array('viewOrder', $this->permission)) {
+ // Afficher pour toutes les commandes sauf celles refusées
+ // Et pour les commandes en attente : seulement si pas de remise OU remise validée
+ if ($value['paid_status'] == 2) {
+ // En attente : vérifier la remise
+ if ($discount == 0 || $Remise->hasRemiseValidatedForOrder($value['id'])) {
+ $buttons .= '
+
+
+ ';
+ }
+ } else {
+ // Payé ou Livré : toujours afficher
+ $buttons .= '
+
+
+ ';
+ }
+ }
+
+ // ✅ Bouton modifier (seulement si paid_status = 2)
+ if (in_array('updateOrder', $this->permission)
+ && $users["store_id"] == $value['store_id']
+ && $value['paid_status'] == 2) {
+
+ // CAS 1 : Pas de remise → Afficher le bouton modifier
+ if ($discount == 0) {
+ $buttons .= ' ';
+ }
+ // CAS 2 : Remise validée → Afficher le bouton modifier
+ elseif ($Remise->hasRemiseValidatedForOrder($value['id'])) {
+ $buttons .= ' ';
+ }
+ }
}
-
+
// Statut de paiement
if ($value['paid_status'] == 1) {
- $paid_status = 'payé';
+ $paid_status = 'Payé';
} elseif ($value['paid_status'] == 2) {
$paid_status = 'En Attente';
} elseif ($value['paid_status'] == 3) {
- $paid_status = 'payé et Livré';
+ $paid_status = 'Payé et Livré';
} else {
$paid_status = 'Refusé';
}
-
+
// Calcul délai
$date1 = new DateTime($date_time);
$date2 = new DateTime();
$interval = $date1->diff($date2);
$daysPassed = $interval->days;
-
+
$statuDate = '';
if ($value['paid_status'] == 2) {
if ($daysPassed < 8) {
@@ -132,7 +201,7 @@ class OrderController extends AdminController
$statuDate = ' depuis ' . $daysPassed . ' Jours';
}
}
-
+
$result['data'][$key] = [
$value['product_names'],
$value['user_name'],
@@ -145,7 +214,7 @@ class OrderController extends AdminController
}
return $this->response->setJSON($result);
}
-
+
// ========================================
// POUR DIRECTION OU DAF
// ========================================
@@ -213,7 +282,7 @@ class OrderController extends AdminController
}
// ========================================
- // POUR LES AUTRES UTILISATEURS (COMMERCIALE, SECURITE, etc.)
+ // POUR LES AUTRES UTILISATEURS (COMMERCIALE, SECURITE, Cheffe d'Agence)
// ========================================
else {
foreach ($data as $key => $value) {
@@ -281,20 +350,58 @@ class OrderController extends AdminController
}
}
- $result['data'][$key] = [
- $value['product_names'],
- $value['user_name'],
- $date_time . "
" . $statuDate,
- number_format((int) $value['discount'], 0, ',', ' '),
- number_format((int) $value['gross_amount'], 0, ',', ' '),
- $paid_status,
- $buttons
- ];
+ // ✅ CONDITION SPÉCIALE POUR SECURITE : remplacer Prix demandé et Prix de vente par Marque et Désignation
+ if ($users['group_name'] == "SECURITE") {
+ // Récupérer les infos produit
+ $OrderItems = new OrderItems();
+ $Products = new Products();
+ $Brands = new Brands();
+
+ $order_items = $OrderItems->getOrdersItemData($value['id']);
+
+ $marque = 'N/A';
+ $numero_serie = 'N/A';
+
+ if (!empty($order_items[0])) {
+ $product = $Products->getProductData($order_items[0]['product_id']);
+
+ if ($product) {
+ $numero_serie = $product['sku'] ?? 'N/A'; // ✅ Numéro de série
+
+ if (!empty($product['marque'])) {
+ $brand = $Brands->find($product['marque']);
+ if ($brand) {
+ $marque = $brand['name'];
+ }
+ }
+ }
+ }
+
+ $result['data'][$key] = [
+ $value['product_names'],
+ $value['user_name'],
+ $date_time . "
" . $statuDate,
+ $marque, // ✅ Remplace Prix demandé
+ $numero_serie, // ✅ Remplace Prix de vente
+ $paid_status,
+ $buttons
+ ];
+ } else {
+ // Pour les autres (COMMERCIALE, Cheffe d'Agence)
+ $result['data'][$key] = [
+ $value['product_names'],
+ $value['user_name'],
+ $date_time . "
" . $statuDate,
+ number_format((int) $value['discount'], 0, ',', ' '),
+ number_format((int) $value['gross_amount'], 0, ',', ' '),
+ $paid_status,
+ $buttons
+ ];
+ }
}
return $this->response->setJSON($result);
}
}
-
/**
* Affiche le formulaire create avec les données d'une commande existante
* Pour le rôle COMMERCIALE
@@ -364,19 +471,25 @@ public function create()
$Products = new Products();
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
-
+
$session = session();
$users = $session->get('user');
$user_id = $users['id'];
- $bill_no = $this->generateBillNo($users['store_id']);
-
+ // Générer le numéro séquentiel
+ $bill_no = $this->generateSimpleSequentialBillNo($users['store_id']);
+
+ // Récupérer le type de document
+ $document_type = $this->request->getPost('document_type') ?? 'facture';
+
$posts = $this->request->getPost('product[]');
$rates = $this->request->getPost('rate_value[]');
$amounts = $this->request->getPost('amount_value[]');
$puissances = $this->request->getPost('puissance[]');
$discount = (float)$this->request->getPost('discount') ?? 0;
$gross_amount = $this->calculGross($amounts);
+ $net_amount = $gross_amount - $discount;
+
// Vérification prix minimal SI rabais existe
if ($discount > 0) {
@@ -405,25 +518,38 @@ public function create()
}
}
- $montant_a_payer = ($discount > 0) ? $discount : $gross_amount;
+ $discount = (float)$this->request->getPost('discount') ?? 0;
+ $gross_amount = $this->calculGross($amounts);
+
+
+ $net_amount = $gross_amount - $discount;
$tranche_1 = (float)$this->request->getPost('tranche_1') ?? 0;
$tranche_2 = (float)$this->request->getPost('tranche_2') ?? 0;
+ // Si des tranches sont définies, vérifier la cohérence
if ($tranche_1 > 0 && $tranche_2 > 0) {
- $net_amount = $tranche_1 + $tranche_2;
- } else {
- $net_amount = $montant_a_payer;
+ $total_tranches = $tranche_1 + $tranche_2;
+ // S'assurer que les tranches correspondent au net_amount
+ if (abs($total_tranches - $net_amount) > 0.01) {
+ return redirect()->back()
+ ->withInput()
+ ->with('errors', [
+ 'Les tranches de paiement ne correspondent pas au montant total (' .
+ number_format($net_amount, 0, ',', ' ') . ' Ar)'
+ ]);
+ }
}
-
+
$data = [
'bill_no' => $bill_no,
+ 'document_type' => $document_type,
'customer_name' => $this->request->getPost('customer_name'),
'customer_address' => $this->request->getPost('customer_address'),
'customer_phone' => $this->request->getPost('customer_phone'),
'customer_cin' => $this->request->getPost('customer_cin'),
- 'customer_type' => $this->request->getPost('customer_type'),
- 'source' => $this->request->getPost('source'),
+ 'customer_type' => $this->request->getPost('customer_type'),
+ 'source' => $this->request->getPost('source'),
'date_time' => date('Y-m-d H:i:s'),
'service_charge_rate' => 0,
'vat_charge_rate' => 0,
@@ -446,7 +572,14 @@ public function create()
$order_id = $Orders->create($data, $posts);
if ($order_id) {
+ // ✅ NOUVEAU : Marquer immédiatement les produits comme réservés
+ $productModel = new Products();
+ foreach ($posts as $product_id) {
+ $productModel->update($product_id, ['product_sold' => 1]);
+ }
+
session()->setFlashdata('success', 'Créé avec succès');
+
$Notification = new NotificationController();
$Stores = new Stores();
@@ -856,6 +989,7 @@ public function update(int $id)
}
$dataUpdate = [
+ 'document_type' => $this->request->getPost('document_type'), // ✅ AJOUTER CETTE LIGNE
'customer_name' => $this->request->getPost('customer_name'),
'customer_address' => $this->request->getPost('customer_address'),
'customer_phone' => $this->request->getPost('customer_phone'),
@@ -1507,21 +1641,35 @@ public function update(int $id)
$this->verifyRole('deleteOrder');
$order_id = $this->request->getPost('order_id');
$response = [];
-
+
if ($order_id) {
$Orders = new Orders();
+ $OrderItems = new OrderItems();
+ $Products = new Products();
+
+ // ✅ Récupérer tous les produits de la commande
+ $orderItems = $OrderItems->getOrdersItemData($order_id);
+
+ // ✅ Libérer chaque produit (remettre product_sold = 0)
+ foreach ($orderItems as $item) {
+ if (!empty($item['product_id'])) {
+ $Products->update($item['product_id'], ['product_sold' => 0]);
+ }
+ }
+
+ // Supprimer la commande
if ($Orders->remove($order_id)) {
-
$response['success'] = true;
$response['messages'] = "Successfully removed";
} else {
$response['success'] = false;
- $response['messages'] = "Error in the database while removing the product information";
+ $response['messages'] = "Error in the database while removing the order";
}
} else {
$response['success'] = false;
$response['messages'] = "Refersh the page again!!";
}
+
return $this->response->setJSON($response);
}
@@ -1550,6 +1698,39 @@ public function update(int $id)
return $this->render_template('orders/createbyid', $data);
}
+
+ public function printDiv(int $id)
+{
+ $Orders = new Orders();
+ $order = $Orders->getOrdersData($id);
+
+ $docType = $order['document_type'] ?? 'facture';
+
+ // Rediriger vers la bonne méthode selon le type
+ switch($docType) {
+ case 'facture':
+ return $this->print31($id); // Factures individuelles
+ case 'bl':
+ return $this->print7($id); // Bon de livraison
+ case 'both':
+ return $this->print31($id); // Factures + Bon de livraison
+ default:
+ return $this->print31($id);
+ }
+}
+
+public function printDivBL(int $id)
+{
+ // Force le bon de livraison
+ return $this->print7($id);
+}
+
+public function printDivBLF(int $id)
+{
+ // Force facture + bon de livraison
+ return $this->print31($id);
+}
+
// update caisse
public function update_caisse($data)
{
@@ -1801,6 +1982,24 @@ public function print5(int $id)
$company = $Company->getCompanyData(1);
$today = date('d/m/Y');
+ // ✅ RÉCUPÉRER LE TYPE DE DOCUMENT
+ $documentType = $order['document_type'] ?? 'facture';
+ $documentTitle = '';
+
+ switch($documentType) {
+ case 'facture':
+ $documentTitle = 'FACTURE';
+ break;
+ case 'bl':
+ $documentTitle = 'BON DE LIVRAISON';
+ break;
+ case 'both':
+ $documentTitle = 'FACTURE & BON DE LIVRAISON';
+ break;
+ default:
+ $documentTitle = 'FACTURE';
+ }
+
// ✅ Vérifier si c'est une avance "sur mer"
$isAvanceMere = false;
foreach ($items as $item) {
@@ -1823,7 +2022,7 @@ public function print5(int $id)
';
- echo 'Facture N° ' . esc($order_data['bill_no']) . '
'; + echo '' . $documentTitle . ' N° ' . esc($order_data['bill_no']) . '
'; echo 'Antananarivo, le ' . date('d/m/Y') . '
'; echo '
';
- echo 'Bon de Commande N° ' . esc($order_data['bill_no']) . '
'; + echo '' . $documentTitle . ' N° ' . esc($order_data['bill_no']) . '
'; echo '