|
|
@ -41,26 +41,46 @@ class OrderController extends AdminController |
|
|
* @param int $store_id |
|
|
* @param int $store_id |
|
|
* @return string |
|
|
* @return string |
|
|
*/ |
|
|
*/ |
|
|
private function generateBillNo(int $store_id): string |
|
|
private function generateSimpleSequentialBillNo(int $store_id): string |
|
|
{ |
|
|
{ |
|
|
// Mapping des préfixes par magasin |
|
|
|
|
|
$storePrefixes = [ |
|
|
$storePrefixes = [ |
|
|
1 => 'ANTS', // ANTSAKAVIRO |
|
|
1 => 'ANTS', |
|
|
2 => 'BESA', // BESARETY |
|
|
2 => 'BESA', |
|
|
3 => 'BYPA', // BYPASS |
|
|
3 => 'BYPA', |
|
|
4 => 'TOAM', // TOAMASINA |
|
|
4 => 'TOAM', |
|
|
]; |
|
|
]; |
|
|
|
|
|
|
|
|
// Récupérer le préfixe du magasin, ou utiliser un préfixe par défaut |
|
|
$prefix = $storePrefixes[$store_id] ?? 'STORE'; |
|
|
$prefix = $storePrefixes[$store_id] ?? 'BILPR'; |
|
|
|
|
|
|
|
|
|
|
|
// Générer un identifiant unique |
|
|
$db = \Config\Database::connect(); |
|
|
$uniqueId = strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 6)); |
|
|
|
|
|
|
|
|
|
|
|
// Retourner le numéro de facture formaté |
|
|
$lastBill = $db->table('orders') |
|
|
return $prefix . '-' . $uniqueId; |
|
|
->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() |
|
|
public function fetchOrdersData() |
|
|
{ |
|
|
{ |
|
|
helper(['url', 'form']); |
|
|
helper(['url', 'form']); |
|
|
@ -75,43 +95,92 @@ class OrderController extends AdminController |
|
|
// POUR CAISSIÈRE |
|
|
// POUR CAISSIÈRE |
|
|
// ======================================== |
|
|
// ======================================== |
|
|
if ($users['group_name'] == "Caissière") { |
|
|
if ($users['group_name'] == "Caissière") { |
|
|
|
|
|
$Remise = new Remise(); |
|
|
|
|
|
|
|
|
foreach ($data as $key => $value) { |
|
|
foreach ($data as $key => $value) { |
|
|
$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 = ''; |
|
|
|
|
|
$discount = (float)$value['discount']; |
|
|
|
|
|
|
|
|
// Bouton imprimer (sauf pour SECURITE) |
|
|
// ✅ VÉRIFICATION : Si la commande est refusée (paid_status = 0), aucun bouton |
|
|
if (in_array('viewOrder', $this->permission) && $users['group_name'] != "SECURITE" && $users['group_name'] != "COMMERCIALE") { |
|
|
if ($value['paid_status'] == 0) { |
|
|
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>'; |
|
|
$buttons = '<span class="label label-danger"><i class="fa fa-ban"></i> Accès bloqué</span>'; |
|
|
} |
|
|
} 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 .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>'; |
|
|
|
|
|
} |
|
|
|
|
|
// CAS 2 : Commande en attente (2) SANS remise → Afficher imprimer |
|
|
|
|
|
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>'; |
|
|
|
|
|
} |
|
|
|
|
|
// CAS 3 : Commande en attente (2) AVEC remise validée → Afficher imprimer |
|
|
|
|
|
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>'; |
|
|
|
|
|
} |
|
|
|
|
|
// CAS 4 : Commande en attente (2) AVEC remise en attente → Indicateur |
|
|
|
|
|
elseif ($value['paid_status'] == 2 && $Remise->hasRemisePendingForOrder($value['id'])) { |
|
|
|
|
|
$buttons .= '<button class="btn btn-warning btn-sm" disabled title="En attente de validation"><i class="fa fa-clock-o"></i></button>'; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Bouton voir |
|
|
// ✅ Bouton voir |
|
|
if (in_array('viewOrder', $this->permission)) { |
|
|
if (in_array('viewOrder', $this->permission)) { |
|
|
$buttons .= ' |
|
|
// Afficher pour toutes les commandes sauf celles refusées |
|
|
<a |
|
|
// Et pour les commandes en attente : seulement si pas de remise OU remise validée |
|
|
href="#" |
|
|
if ($value['paid_status'] == 2) { |
|
|
data-order-id="' . $value['id'] . '" |
|
|
// En attente : vérifier la remise |
|
|
class="btn btn-default btn-view" |
|
|
if ($discount == 0 || $Remise->hasRemiseValidatedForOrder($value['id'])) { |
|
|
data-toggle="tooltip" |
|
|
$buttons .= ' |
|
|
title="Voir"> |
|
|
<a |
|
|
<i class="fa fa-eye"></i> |
|
|
href="#" |
|
|
</a>'; |
|
|
data-order-id="' . $value['id'] . '" |
|
|
} |
|
|
class="btn btn-default btn-view" |
|
|
|
|
|
data-toggle="tooltip" |
|
|
|
|
|
title="Voir"> |
|
|
|
|
|
<i class="fa fa-eye"></i> |
|
|
|
|
|
</a>'; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// Payé ou Livré : toujours afficher |
|
|
|
|
|
$buttons .= ' |
|
|
|
|
|
<a |
|
|
|
|
|
href="#" |
|
|
|
|
|
data-order-id="' . $value['id'] . '" |
|
|
|
|
|
class="btn btn-default btn-view" |
|
|
|
|
|
data-toggle="tooltip" |
|
|
|
|
|
title="Voir"> |
|
|
|
|
|
<i class="fa fa-eye"></i> |
|
|
|
|
|
</a>'; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// ✅ Bouton modifier pour statuts 0 (Refusé) et 2 (En Attente) |
|
|
// ✅ Bouton modifier (seulement si paid_status = 2) |
|
|
if (in_array('updateOrder', $this->permission) |
|
|
if (in_array('updateOrder', $this->permission) |
|
|
&& $users["store_id"] == $value['store_id'] |
|
|
&& $users["store_id"] == $value['store_id'] |
|
|
&& in_array($value['paid_status'], [0, 2])) { |
|
|
&& $value['paid_status'] == 2) { |
|
|
$buttons .= ' <a href="' . site_url('orders/update/' . $value['id']) . '" class="btn btn-primary"><i class="fa fa-pencil"></i></a>'; |
|
|
|
|
|
|
|
|
// CAS 1 : Pas de remise → Afficher le bouton modifier |
|
|
|
|
|
if ($discount == 0) { |
|
|
|
|
|
$buttons .= ' <a href="' . site_url('orders/update/' . $value['id']) . '" class="btn btn-primary"><i class="fa fa-pencil"></i></a>'; |
|
|
|
|
|
} |
|
|
|
|
|
// CAS 2 : Remise validée → Afficher le bouton modifier |
|
|
|
|
|
elseif ($Remise->hasRemiseValidatedForOrder($value['id'])) { |
|
|
|
|
|
$buttons .= ' <a href="' . site_url('orders/update/' . $value['id']) . '" class="btn btn-primary"><i class="fa fa-pencil"></i></a>'; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Statut de paiement |
|
|
// Statut de paiement |
|
|
if ($value['paid_status'] == 1) { |
|
|
if ($value['paid_status'] == 1) { |
|
|
$paid_status = '<span class="label label-success">payé</span>'; |
|
|
$paid_status = '<span class="label label-success">Payé</span>'; |
|
|
} elseif ($value['paid_status'] == 2) { |
|
|
} elseif ($value['paid_status'] == 2) { |
|
|
$paid_status = '<span class="label label-warning">En Attente</span>'; |
|
|
$paid_status = '<span class="label label-warning">En Attente</span>'; |
|
|
} elseif ($value['paid_status'] == 3) { |
|
|
} elseif ($value['paid_status'] == 3) { |
|
|
$paid_status = '<span class="label label-info">payé et Livré</span>'; |
|
|
$paid_status = '<span class="label label-info">Payé et Livré</span>'; |
|
|
} else { |
|
|
} else { |
|
|
$paid_status = '<span class="label label-danger">Refusé</span>'; |
|
|
$paid_status = '<span class="label label-danger">Refusé</span>'; |
|
|
} |
|
|
} |
|
|
@ -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 { |
|
|
else { |
|
|
foreach ($data as $key => $value) { |
|
|
foreach ($data as $key => $value) { |
|
|
@ -281,20 +350,58 @@ class OrderController extends AdminController |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
$result['data'][$key] = [ |
|
|
// ✅ CONDITION SPÉCIALE POUR SECURITE : remplacer Prix demandé et Prix de vente par Marque et Désignation |
|
|
$value['product_names'], |
|
|
if ($users['group_name'] == "SECURITE") { |
|
|
$value['user_name'], |
|
|
// Récupérer les infos produit |
|
|
$date_time . " <br >" . $statuDate, |
|
|
$OrderItems = new OrderItems(); |
|
|
number_format((int) $value['discount'], 0, ',', ' '), |
|
|
$Products = new Products(); |
|
|
number_format((int) $value['gross_amount'], 0, ',', ' '), |
|
|
$Brands = new Brands(); |
|
|
$paid_status, |
|
|
|
|
|
$buttons |
|
|
$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 . " <br >" . $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 . " <br >" . $statuDate, |
|
|
|
|
|
number_format((int) $value['discount'], 0, ',', ' '), |
|
|
|
|
|
number_format((int) $value['gross_amount'], 0, ',', ' '), |
|
|
|
|
|
$paid_status, |
|
|
|
|
|
$buttons |
|
|
|
|
|
]; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
return $this->response->setJSON($result); |
|
|
return $this->response->setJSON($result); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Affiche le formulaire create avec les données d'une commande existante |
|
|
* Affiche le formulaire create avec les données d'une commande existante |
|
|
* Pour le rôle COMMERCIALE |
|
|
* Pour le rôle COMMERCIALE |
|
|
@ -369,7 +476,11 @@ public function create() |
|
|
$users = $session->get('user'); |
|
|
$users = $session->get('user'); |
|
|
$user_id = $users['id']; |
|
|
$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[]'); |
|
|
$posts = $this->request->getPost('product[]'); |
|
|
$rates = $this->request->getPost('rate_value[]'); |
|
|
$rates = $this->request->getPost('rate_value[]'); |
|
|
@ -377,6 +488,8 @@ public function create() |
|
|
$puissances = $this->request->getPost('puissance[]'); |
|
|
$puissances = $this->request->getPost('puissance[]'); |
|
|
$discount = (float)$this->request->getPost('discount') ?? 0; |
|
|
$discount = (float)$this->request->getPost('discount') ?? 0; |
|
|
$gross_amount = $this->calculGross($amounts); |
|
|
$gross_amount = $this->calculGross($amounts); |
|
|
|
|
|
$net_amount = $gross_amount - $discount; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Vérification prix minimal SI rabais existe |
|
|
// Vérification prix minimal SI rabais existe |
|
|
if ($discount > 0) { |
|
|
if ($discount > 0) { |
|
|
@ -405,19 +518,32 @@ 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_1 = (float)$this->request->getPost('tranche_1') ?? 0; |
|
|
$tranche_2 = (float)$this->request->getPost('tranche_2') ?? 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) { |
|
|
if ($tranche_1 > 0 && $tranche_2 > 0) { |
|
|
$net_amount = $tranche_1 + $tranche_2; |
|
|
$total_tranches = $tranche_1 + $tranche_2; |
|
|
} else { |
|
|
// S'assurer que les tranches correspondent au net_amount |
|
|
$net_amount = $montant_a_payer; |
|
|
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 = [ |
|
|
$data = [ |
|
|
'bill_no' => $bill_no, |
|
|
'bill_no' => $bill_no, |
|
|
|
|
|
'document_type' => $document_type, |
|
|
'customer_name' => $this->request->getPost('customer_name'), |
|
|
'customer_name' => $this->request->getPost('customer_name'), |
|
|
'customer_address' => $this->request->getPost('customer_address'), |
|
|
'customer_address' => $this->request->getPost('customer_address'), |
|
|
'customer_phone' => $this->request->getPost('customer_phone'), |
|
|
'customer_phone' => $this->request->getPost('customer_phone'), |
|
|
@ -446,8 +572,15 @@ public function create() |
|
|
$order_id = $Orders->create($data, $posts); |
|
|
$order_id = $Orders->create($data, $posts); |
|
|
|
|
|
|
|
|
if ($order_id) { |
|
|
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'); |
|
|
session()->setFlashdata('success', 'Créé avec succès'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$Notification = new NotificationController(); |
|
|
$Notification = new NotificationController(); |
|
|
$Stores = new Stores(); |
|
|
$Stores = new Stores(); |
|
|
|
|
|
|
|
|
@ -856,6 +989,7 @@ public function update(int $id) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
$dataUpdate = [ |
|
|
$dataUpdate = [ |
|
|
|
|
|
'document_type' => $this->request->getPost('document_type'), // ✅ AJOUTER CETTE LIGNE |
|
|
'customer_name' => $this->request->getPost('customer_name'), |
|
|
'customer_name' => $this->request->getPost('customer_name'), |
|
|
'customer_address' => $this->request->getPost('customer_address'), |
|
|
'customer_address' => $this->request->getPost('customer_address'), |
|
|
'customer_phone' => $this->request->getPost('customer_phone'), |
|
|
'customer_phone' => $this->request->getPost('customer_phone'), |
|
|
@ -1510,18 +1644,32 @@ public function update(int $id) |
|
|
|
|
|
|
|
|
if ($order_id) { |
|
|
if ($order_id) { |
|
|
$Orders = new Orders(); |
|
|
$Orders = new Orders(); |
|
|
if ($Orders->remove($order_id)) { |
|
|
$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['success'] = true; |
|
|
$response['messages'] = "Successfully removed"; |
|
|
$response['messages'] = "Successfully removed"; |
|
|
} else { |
|
|
} else { |
|
|
$response['success'] = false; |
|
|
$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 { |
|
|
} else { |
|
|
$response['success'] = false; |
|
|
$response['success'] = false; |
|
|
$response['messages'] = "Refersh the page again!!"; |
|
|
$response['messages'] = "Refersh the page again!!"; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return $this->response->setJSON($response); |
|
|
return $this->response->setJSON($response); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -1550,6 +1698,39 @@ public function update(int $id) |
|
|
return $this->render_template('orders/createbyid', $data); |
|
|
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 |
|
|
// update caisse |
|
|
public function update_caisse($data) |
|
|
public function update_caisse($data) |
|
|
{ |
|
|
{ |
|
|
@ -1801,6 +1982,24 @@ public function print5(int $id) |
|
|
$company = $Company->getCompanyData(1); |
|
|
$company = $Company->getCompanyData(1); |
|
|
$today = date('d/m/Y'); |
|
|
$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" |
|
|
// ✅ Vérifier si c'est une avance "sur mer" |
|
|
$isAvanceMere = false; |
|
|
$isAvanceMere = false; |
|
|
foreach ($items as $item) { |
|
|
foreach ($items as $item) { |
|
|
@ -1823,7 +2022,7 @@ public function print5(int $id) |
|
|
<html lang="fr"> |
|
|
<html lang="fr"> |
|
|
<head> |
|
|
<head> |
|
|
<meta charset="utf-8"> |
|
|
<meta charset="utf-8"> |
|
|
<title>Facture '.$order['bill_no'].'</title> |
|
|
<title>'.$documentTitle.' '.$order['bill_no'].'</title> |
|
|
<style> |
|
|
<style> |
|
|
/* ✅ FORMAT A4 PAYSAGE DIVISÉ EN 2 */ |
|
|
/* ✅ FORMAT A4 PAYSAGE DIVISÉ EN 2 */ |
|
|
@page { |
|
|
@page { |
|
|
@ -2001,10 +2200,10 @@ public function print5(int $id) |
|
|
</head> |
|
|
</head> |
|
|
<body onload="window.print()"> |
|
|
<body onload="window.print()"> |
|
|
|
|
|
|
|
|
<!-- ✅ PAGE 1 : RECTO - 2 FACTURES CÔTE À CÔTE --> |
|
|
<!-- ✅ PAGE 1 : RECTO - 2 DOCUMENTS CÔTE À CÔTE --> |
|
|
<div class="page">'; |
|
|
<div class="page">'; |
|
|
|
|
|
|
|
|
// ✅ GÉNÉRER 2 FACTURES IDENTIQUES |
|
|
// ✅ GÉNÉRER 2 DOCUMENTS IDENTIQUES |
|
|
for ($i = 0; $i < 2; $i++) { |
|
|
for ($i = 0; $i < 2; $i++) { |
|
|
$html .= ' |
|
|
$html .= ' |
|
|
<div class="facture-box"> |
|
|
<div class="facture-box"> |
|
|
@ -2017,7 +2216,7 @@ public function print5(int $id) |
|
|
</div> |
|
|
</div> |
|
|
<div style="text-align:center;"> |
|
|
<div style="text-align:center;"> |
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo"> |
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo"> |
|
|
<p class="facture-num">Facture N° '.esc($order['bill_no']).'</p> |
|
|
<p class="facture-num">'.$documentTitle.' N° '.esc($order['bill_no']).'</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
@ -2059,7 +2258,6 @@ public function print5(int $id) |
|
|
</tr>'; |
|
|
</tr>'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ✅ CORRECTION : Fermer le tableau pour avance |
|
|
|
|
|
$html .= ' |
|
|
$html .= ' |
|
|
</tbody> |
|
|
</tbody> |
|
|
</table>'; |
|
|
</table>'; |
|
|
@ -2097,7 +2295,6 @@ public function print5(int $id) |
|
|
</tr>'; |
|
|
</tr>'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ✅ Fermer le tableau pour produit normal |
|
|
|
|
|
$html .= ' |
|
|
$html .= ' |
|
|
</tbody> |
|
|
</tbody> |
|
|
</table>'; |
|
|
</table>'; |
|
|
@ -2322,17 +2519,33 @@ public function print7(int $id) |
|
|
throw new \CodeIgniter\Exceptions\PageNotFoundException(); |
|
|
throw new \CodeIgniter\Exceptions\PageNotFoundException(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Modèles |
|
|
|
|
|
$Orders = new Orders(); |
|
|
$Orders = new Orders(); |
|
|
$Company = new Company(); |
|
|
$Company = new Company(); |
|
|
$OrderItems = new OrderItems(); |
|
|
$OrderItems = new OrderItems(); |
|
|
|
|
|
|
|
|
// Récupération des données |
|
|
|
|
|
$order = $Orders->getOrdersData($id); |
|
|
$order = $Orders->getOrdersData($id); |
|
|
$items = $OrderItems->getOrdersItemData($id); |
|
|
$items = $OrderItems->getOrdersItemData($id); |
|
|
$company = $Company->getCompanyData(1); |
|
|
$company = $Company->getCompanyData(1); |
|
|
$today = date('d/m/Y'); |
|
|
$today = date('d/m/Y'); |
|
|
|
|
|
|
|
|
|
|
|
// ✅ RÉCUPÉRER LE TYPE DE DOCUMENT |
|
|
|
|
|
$documentType = $order['document_type'] ?? 'bl'; |
|
|
|
|
|
$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 = 'BON DE LIVRAISON'; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// ✅ VÉRIFIER SI C'EST UNE AVANCE "SUR MER" |
|
|
// ✅ VÉRIFIER SI C'EST UNE AVANCE "SUR MER" |
|
|
$isAvanceMere = false; |
|
|
$isAvanceMere = false; |
|
|
foreach ($items as $item) { |
|
|
foreach ($items as $item) { |
|
|
@ -2342,7 +2555,6 @@ public function print7(int $id) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ✅ LOGIQUE DE REMISE |
|
|
|
|
|
$discount = (float) $order['discount']; |
|
|
$discount = (float) $order['discount']; |
|
|
$grossAmount = (float) $order['gross_amount']; |
|
|
$grossAmount = (float) $order['gross_amount']; |
|
|
$totalTTC = ($discount > 0) ? $discount : $grossAmount; |
|
|
$totalTTC = ($discount > 0) ? $discount : $grossAmount; |
|
|
@ -2351,12 +2563,11 @@ public function print7(int $id) |
|
|
|
|
|
|
|
|
$paidLabel = $order['paid_status'] == 1 ? 'Payé' : 'Non payé'; |
|
|
$paidLabel = $order['paid_status'] == 1 ? 'Payé' : 'Non payé'; |
|
|
|
|
|
|
|
|
// Démarrage du HTML |
|
|
|
|
|
$html = '<!DOCTYPE html> |
|
|
$html = '<!DOCTYPE html> |
|
|
<html lang="fr"> |
|
|
<html lang="fr"> |
|
|
<head> |
|
|
<head> |
|
|
<meta charset="utf-8"> |
|
|
<meta charset="utf-8"> |
|
|
<title>Bon de commande '.$order['bill_no'].'</title> |
|
|
<title>'.$documentTitle.' '.$order['bill_no'].'</title> |
|
|
<style> |
|
|
<style> |
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; } |
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; } |
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin:20px; } |
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin:20px; } |
|
|
@ -2388,7 +2599,7 @@ public function print7(int $id) |
|
|
</div> |
|
|
</div> |
|
|
<div style="text-align:center;"> |
|
|
<div style="text-align:center;"> |
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo"> |
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo"> |
|
|
<p style="margin:5px 0; font-weight:bold;">Bon de commande N° '.esc($order['bill_no']).'</p> |
|
|
<p style="margin:5px 0; font-weight:bold;">'.$documentTitle.' N° '.esc($order['bill_no']).'</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
@ -2400,11 +2611,8 @@ public function print7(int $id) |
|
|
<p style="text-align:right;"><em>Antananarivo, le '.$today.'</em></p> |
|
|
<p style="text-align:right;"><em>Antananarivo, le '.$today.'</em></p> |
|
|
</div>'; |
|
|
</div>'; |
|
|
|
|
|
|
|
|
// ======================================== |
|
|
|
|
|
// ✅ TABLEAU ADAPTÉ SELON LE TYPE |
|
|
// ✅ TABLEAU ADAPTÉ SELON LE TYPE |
|
|
// ======================================== |
|
|
|
|
|
if ($isAvanceMere) { |
|
|
if ($isAvanceMere) { |
|
|
// --- TABLE SIMPLIFIÉE POUR AVANCE "SUR MER" (2-3 COLONNES) --- |
|
|
|
|
|
$html .= ' |
|
|
$html .= ' |
|
|
<table> |
|
|
<table> |
|
|
<thead> |
|
|
<thead> |
|
|
@ -2426,7 +2634,6 @@ public function print7(int $id) |
|
|
<tr> |
|
|
<tr> |
|
|
<td>'.esc($details['product_name']); |
|
|
<td>'.esc($details['product_name']); |
|
|
|
|
|
|
|
|
// Afficher le commentaire s'il existe |
|
|
|
|
|
if (!empty($details['commentaire'])) { |
|
|
if (!empty($details['commentaire'])) { |
|
|
$html .= '<br><em style="font-size:12px; color:#666;">Remarque : '.esc($details['commentaire']).'</em>'; |
|
|
$html .= '<br><em style="font-size:12px; color:#666;">Remarque : '.esc($details['commentaire']).'</em>'; |
|
|
} |
|
|
} |
|
|
@ -2441,7 +2648,6 @@ public function print7(int $id) |
|
|
</table>'; |
|
|
</table>'; |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// --- TABLE COMPLÈTE POUR AVANCE "SUR TERRE" OU COMMANDE NORMALE (7 COLONNES) --- |
|
|
|
|
|
$html .= ' |
|
|
$html .= ' |
|
|
<table> |
|
|
<table> |
|
|
<thead> |
|
|
<thead> |
|
|
@ -2468,7 +2674,6 @@ public function print7(int $id) |
|
|
|
|
|
|
|
|
$prixAffiche = ($discount > 0) ? $discount : $details['prix']; |
|
|
$prixAffiche = ($discount > 0) ? $discount : $details['prix']; |
|
|
|
|
|
|
|
|
// Récupérer la catégorie si c'est un produit terre |
|
|
|
|
|
$categoryName = 'Non définie'; |
|
|
$categoryName = 'Non définie'; |
|
|
if ($details['type'] === 'terre' && !empty($item['product_id'])) { |
|
|
if ($details['type'] === 'terre' && !empty($item['product_id'])) { |
|
|
$p = $Products->getProductData($item['product_id']); |
|
|
$p = $Products->getProductData($item['product_id']); |
|
|
@ -2497,9 +2702,6 @@ public function print7(int $id) |
|
|
</table>'; |
|
|
</table>'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ======================================== |
|
|
|
|
|
// TABLEAU RÉCAPITULATIF (IDENTIQUE POUR TOUS) |
|
|
|
|
|
// ======================================== |
|
|
|
|
|
$html .= ' |
|
|
$html .= ' |
|
|
<table style="width:calc(100% - 40px); margin:0 20px 20px;"> |
|
|
<table style="width:calc(100% - 40px); margin:0 20px 20px;"> |
|
|
<tr> |
|
|
<tr> |
|
|
@ -2555,7 +2757,6 @@ public function print7(int $id) |
|
|
Merci pour votre confiance |
|
|
Merci pour votre confiance |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<!-- Conditions Générales avec saut de page --> |
|
|
|
|
|
<div class="conditions"> |
|
|
<div class="conditions"> |
|
|
<div style="display:flex; justify-content:space-between; align-items:center;"> |
|
|
<div style="display:flex; justify-content:space-between; align-items:center;"> |
|
|
<h3 style="margin:0;">Conditions Générales</h3> |
|
|
<h3 style="margin:0;">Conditions Générales</h3> |
|
|
@ -2576,6 +2777,7 @@ public function print7(int $id) |
|
|
|
|
|
|
|
|
return $this->response->setBody($html); |
|
|
return $this->response->setBody($html); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ==================================== |
|
|
// ==================================== |
|
|
// PRINT31 - Facture + Bon de commande (pages séparées) |
|
|
// PRINT31 - Facture + Bon de commande (pages séparées) |
|
|
// ==================================== |
|
|
// ==================================== |
|
|
@ -2598,6 +2800,24 @@ public function print31(int $id) |
|
|
$items = $OrderItems->getOrdersItemData($id); |
|
|
$items = $OrderItems->getOrdersItemData($id); |
|
|
$company_info = $Company->getCompanyData(1); |
|
|
$company_info = $Company->getCompanyData(1); |
|
|
|
|
|
|
|
|
|
|
|
// ✅ RÉCUPÉRER LE TYPE DE DOCUMENT |
|
|
|
|
|
$documentType = $order_data['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" |
|
|
// ✅ Vérifier si c'est une avance "sur mer" |
|
|
$isAvanceMere = false; |
|
|
$isAvanceMere = false; |
|
|
foreach ($items as $item) { |
|
|
foreach ($items as $item) { |
|
|
@ -2611,51 +2831,49 @@ public function print31(int $id) |
|
|
? "<span style='color: green; font-weight: bold;'>Payé</span>" |
|
|
? "<span style='color: green; font-weight: bold;'>Payé</span>" |
|
|
: "<span style='color: red; font-weight: bold;'>Refusé</span>"; |
|
|
: "<span style='color: red; font-weight: bold;'>Refusé</span>"; |
|
|
|
|
|
|
|
|
// Calculs globaux |
|
|
|
|
|
$discount = (float) $order_data['discount']; |
|
|
$discount = (float) $order_data['discount']; |
|
|
$grossAmount = (float) $order_data['gross_amount']; |
|
|
$grossAmount = (float) $order_data['gross_amount']; |
|
|
$totalTTC = ($discount > 0) ? $discount : $grossAmount; |
|
|
$totalTTC = ($discount > 0) ? $discount : $grossAmount; |
|
|
$totalHT = $totalTTC / 1.20; |
|
|
$totalHT = $totalTTC / 1.20; |
|
|
$tva = $totalTTC - $totalHT; |
|
|
$tva = $totalTTC - $totalHT; |
|
|
|
|
|
|
|
|
|
|
|
$style = ' |
|
|
|
|
|
<style> |
|
|
|
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; } |
|
|
|
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; } |
|
|
|
|
|
.header .infos { line-height:1.4; } |
|
|
|
|
|
.header img { max-height:80px; } |
|
|
|
|
|
.client { margin-bottom:20px; } |
|
|
|
|
|
table { width:100%; border-collapse:collapse; margin-bottom:20px; } |
|
|
|
|
|
th, td { border:1px solid #000; padding:6px; text-align:left; } |
|
|
|
|
|
th { background:#f0f0f0; } |
|
|
|
|
|
.right { text-align:right; } |
|
|
|
|
|
.signature { display:flex; justify-content:space-between; margin-top:50px; } |
|
|
|
|
|
.signature div { text-align:center; } |
|
|
|
|
|
.page-break { page-break-after: always; } |
|
|
|
|
|
.to-fill { border-bottom: 1px dotted #000; min-width: 150px; display: inline-block; } |
|
|
|
|
|
.conditions { page-break-before: always; padding:20px; line-height:1.5; } |
|
|
|
|
|
@media print { |
|
|
|
|
|
body { font-size: 14px; } |
|
|
|
|
|
@page { margin: 1cm; } |
|
|
|
|
|
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; } |
|
|
|
|
|
} |
|
|
|
|
|
</style>'; |
|
|
|
|
|
|
|
|
// --- FACTURES : Une par produit --- |
|
|
// --- FACTURES : Une par produit --- |
|
|
foreach ($items as $item) { |
|
|
foreach ($items as $item) { |
|
|
// ✅ Utiliser getOrderItemDetails au lieu de getProductData directement |
|
|
|
|
|
$details = $this->getOrderItemDetails($item); |
|
|
$details = $this->getOrderItemDetails($item); |
|
|
|
|
|
|
|
|
if (!$details) continue; |
|
|
if (!$details) continue; |
|
|
|
|
|
|
|
|
$unitPrice = $details['prix']; |
|
|
$unitPrice = $details['prix']; |
|
|
$quantity = isset($item['qty']) ? (int) $item['qty'] : 1; |
|
|
|
|
|
$subtotal = $unitPrice * $quantity; |
|
|
|
|
|
|
|
|
|
|
|
// ✅ Pour avance sur mer avec remise, utiliser la remise comme prix |
|
|
|
|
|
$prixAffiche = ($discount > 0 && $isAvanceMere) ? $discount : $unitPrice; |
|
|
$prixAffiche = ($discount > 0 && $isAvanceMere) ? $discount : $unitPrice; |
|
|
|
|
|
|
|
|
echo '<!DOCTYPE html>'; |
|
|
echo '<!DOCTYPE html>'; |
|
|
echo '<html lang="fr">'; |
|
|
echo '<html lang="fr">'; |
|
|
echo '<head><meta charset="utf-8">'; |
|
|
echo '<head><meta charset="utf-8">'; |
|
|
echo '<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">'; |
|
|
echo '<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">'; |
|
|
echo "<style> |
|
|
echo $style; |
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; } |
|
|
|
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; } |
|
|
|
|
|
.header .infos { line-height:1.4; } |
|
|
|
|
|
.header img { max-height:80px; } |
|
|
|
|
|
.client { margin-bottom:20px; } |
|
|
|
|
|
table { width:100%; border-collapse:collapse; margin-bottom:20px; } |
|
|
|
|
|
th, td { border:1px solid #000; padding:6px; text-align:left; } |
|
|
|
|
|
th { background:#f0f0f0; } |
|
|
|
|
|
.right { text-align:right; } |
|
|
|
|
|
.signature { display:flex; justify-content:space-between; margin-top:50px; } |
|
|
|
|
|
.signature div { text-align:center; } |
|
|
|
|
|
.page-break { page-break-after: always; } |
|
|
|
|
|
.to-fill { border-bottom: 1px dotted #000; min-width: 150px; display: inline-block; } |
|
|
|
|
|
@media print { |
|
|
|
|
|
body { font-size: 14px; } |
|
|
|
|
|
@page { margin: 1cm; } |
|
|
|
|
|
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; } |
|
|
|
|
|
} |
|
|
|
|
|
</style>"; |
|
|
|
|
|
echo '</head><body onload="window.print()">'; |
|
|
echo '</head><body onload="window.print()">'; |
|
|
echo '<div class="page-break">'; |
|
|
echo '<div class="page-break">'; |
|
|
echo '<div class="header">'; |
|
|
echo '<div class="header">'; |
|
|
@ -2668,7 +2886,7 @@ public function print31(int $id) |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
echo '<div style="text-align:center;">'; |
|
|
echo '<div style="text-align:center;">'; |
|
|
echo '<img src="' . base_url('assets/images/company_logo.jpg') . '" alt="Logo">'; |
|
|
echo '<img src="' . base_url('assets/images/company_logo.jpg') . '" alt="Logo">'; |
|
|
echo '<p style="margin:5px 0; font-weight:bold;">Facture N° ' . esc($order_data['bill_no']) . '</p>'; |
|
|
echo '<p style="margin:5px 0; font-weight:bold;">' . $documentTitle . ' N° ' . esc($order_data['bill_no']) . '</p>'; |
|
|
echo '<p style="margin:5px 0;"><em>Antananarivo, le ' . date('d/m/Y') . '</em></p>'; |
|
|
echo '<p style="margin:5px 0;"><em>Antananarivo, le ' . date('d/m/Y') . '</em></p>'; |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
@ -2694,7 +2912,6 @@ public function print31(int $id) |
|
|
echo '<td class="right">' . number_format($prixAffiche, 0, '', ' ') . '</td>'; |
|
|
echo '<td class="right">' . number_format($prixAffiche, 0, '', ' ') . '</td>'; |
|
|
echo '</tr>'; |
|
|
echo '</tr>'; |
|
|
|
|
|
|
|
|
// Afficher commentaire si existant |
|
|
|
|
|
if (!empty($details['commentaire'])) { |
|
|
if (!empty($details['commentaire'])) { |
|
|
echo '<tr><td colspan="3"><em style="font-size:12px; color:#666;">Remarque : ' . esc($details['commentaire']) . '</em></td></tr>'; |
|
|
echo '<tr><td colspan="3"><em style="font-size:12px; color:#666;">Remarque : ' . esc($details['commentaire']) . '</em></td></tr>'; |
|
|
} |
|
|
} |
|
|
@ -2702,7 +2919,6 @@ public function print31(int $id) |
|
|
echo '</tbody></table>'; |
|
|
echo '</tbody></table>'; |
|
|
} else { |
|
|
} else { |
|
|
// TABLE COMPLÈTE POUR AVANCE "SUR TERRE" OU COMMANDE NORMALE |
|
|
// TABLE COMPLÈTE POUR AVANCE "SUR TERRE" OU COMMANDE NORMALE |
|
|
// Récupérer catégorie |
|
|
|
|
|
$categoryName = 'Non définie'; |
|
|
$categoryName = 'Non définie'; |
|
|
if ($details['type'] === 'terre' && !empty($item['product_id'])) { |
|
|
if ($details['type'] === 'terre' && !empty($item['product_id'])) { |
|
|
$p = $Products->getProductData($item['product_id']); |
|
|
$p = $Products->getProductData($item['product_id']); |
|
|
@ -2762,31 +2978,12 @@ public function print31(int $id) |
|
|
echo '</body></html>'; |
|
|
echo '</body></html>'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// --- BON DE COMMANDE (UNE SEULE PAGE) --- |
|
|
// --- BON DE LIVRAISON (UNE SEULE PAGE) --- |
|
|
echo '<!DOCTYPE html>'; |
|
|
echo '<!DOCTYPE html>'; |
|
|
echo '<html lang="fr">'; |
|
|
echo '<html lang="fr">'; |
|
|
echo '<head><meta charset="utf-8">'; |
|
|
echo '<head><meta charset="utf-8">'; |
|
|
echo '<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">'; |
|
|
echo '<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">'; |
|
|
echo "<style> |
|
|
echo $style; |
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; } |
|
|
|
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; } |
|
|
|
|
|
.header .infos { line-height:1.4; } |
|
|
|
|
|
.header img { max-height:80px; } |
|
|
|
|
|
.client { margin-bottom:20px; } |
|
|
|
|
|
table { width:100%; border-collapse:collapse; margin-bottom:20px; } |
|
|
|
|
|
th, td { border:1px solid #000; padding:6px; text-align:left; } |
|
|
|
|
|
th { background:#f0f0f0; } |
|
|
|
|
|
.right { text-align:right; } |
|
|
|
|
|
.signature { display:flex; justify-content:space-between; margin-top:50px; } |
|
|
|
|
|
.signature div { text-align:center; } |
|
|
|
|
|
.to-fill { border-bottom: 1px dotted #000; min-width: 150px; display: inline-block; } |
|
|
|
|
|
.conditions { page-break-before: always; padding:20px; line-height:1.5; } |
|
|
|
|
|
@media print { |
|
|
|
|
|
body { font-size: 14px; } |
|
|
|
|
|
@page { margin: 1cm; } |
|
|
|
|
|
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; } |
|
|
|
|
|
} |
|
|
|
|
|
</style>"; |
|
|
|
|
|
echo '</head><body>'; |
|
|
echo '</head><body>'; |
|
|
|
|
|
|
|
|
echo '<div class="header">'; |
|
|
echo '<div class="header">'; |
|
|
@ -2798,7 +2995,7 @@ public function print31(int $id) |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
echo '<div style="text-align:center;">'; |
|
|
echo '<div style="text-align:center;">'; |
|
|
echo '<img src="' . base_url('assets/images/company_logo.jpg') . '" alt="Logo">'; |
|
|
echo '<img src="' . base_url('assets/images/company_logo.jpg') . '" alt="Logo">'; |
|
|
echo '<p style="margin:5px 0; font-weight:bold;">Bon de Commande N° ' . esc($order_data['bill_no']) . '</p>'; |
|
|
echo '<p style="margin:5px 0; font-weight:bold;">' . $documentTitle . ' N° ' . esc($order_data['bill_no']) . '</p>'; |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
echo '</div>'; |
|
|
|
|
|
|
|
|
@ -2842,7 +3039,6 @@ public function print31(int $id) |
|
|
|
|
|
|
|
|
$prixAffiche = ($discount > 0) ? $discount : $details['prix']; |
|
|
$prixAffiche = ($discount > 0) ? $discount : $details['prix']; |
|
|
|
|
|
|
|
|
// Catégorie |
|
|
|
|
|
$categoryName = 'Non définie'; |
|
|
$categoryName = 'Non définie'; |
|
|
if ($details['type'] === 'terre' && !empty($item['product_id'])) { |
|
|
if ($details['type'] === 'terre' && !empty($item['product_id'])) { |
|
|
$p = $Products->getProductData($item['product_id']); |
|
|
$p = $Products->getProductData($item['product_id']); |
|
|
|