Sarobidy22 1 month ago
parent
commit
25d8f834f5
  1. 259
      app/Controllers/AvanceController.php
  2. 1165
      app/Controllers/OrderController.php
  3. 49
      app/Models/OrderItems.php
  4. 39
      app/Models/Orders.php
  5. 80
      app/Views/orders/createbyid.php
  6. 676
      app/Views/orders/edit.php
  7. 4
      app/Views/orders/index.php

259
app/Controllers/AvanceController.php

@ -1635,8 +1635,10 @@ private function generatePrintableInvoiceHTML($avance, $productName, $productDet
<title>Facture Avance - KELY SCOOTERS</title> <title>Facture Avance - KELY SCOOTERS</title>
<style> <style>
@media print { @media print {
body { margin: 0; padding: 10px; } body { margin: 0; padding: 0; }
.no-print { display: none !important; } .no-print { display: none !important; }
.page { page-break-after: always; }
.page:last-child { page-break-after: auto; }
} }
* { margin: 0; padding: 0; box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; }
@ -1646,15 +1648,22 @@ private function generatePrintableInvoiceHTML($avance, $productName, $productDet
font-size: 12px; font-size: 12px;
line-height: 1.4; line-height: 1.4;
background: #fff; background: #fff;
padding: 20px;
} }
.invoice-container { .page {
max-width: 800px; width: 210mm;
height: 297mm;
padding: 15mm;
margin: 0 auto; margin: 0 auto;
background: white; background: white;
}
.invoice-container {
border: 2px solid #000; border: 2px solid #000;
padding: 20px; padding: 20px;
height: 100%;
display: flex;
flex-direction: column;
} }
.header { .header {
@ -1730,6 +1739,24 @@ private function generatePrintableInvoiceHTML($avance, $productName, $productDet
font-weight: bold; font-weight: bold;
} }
.signature-section {
display: flex;
justify-content: space-between;
margin-top: auto;
padding: 20px 0;
}
.signature-box {
text-align: center;
width: 45%;
}
.signature-box p {
font-weight: bold;
margin-bottom: 50px;
}
/* Style spécifique pour le verso */
.contract-section { .contract-section {
margin-top: 20px; margin-top: 20px;
padding: 15px; padding: 15px;
@ -1752,123 +1779,138 @@ private function generatePrintableInvoiceHTML($avance, $productName, $productDet
text-decoration: underline; text-decoration: underline;
} }
.signature-section { .verso-content {
flex: 1;
display: flex; display: flex;
justify-content: space-between; flex-direction: column;
margin-top: 30px;
padding: 20px 0;
}
.signature-box {
text-align: center;
width: 45%;
}
.signature-box p {
font-weight: bold;
margin-bottom: 50px;
} }
</style> </style>
</head> </head>
<body> <body>
<div class="invoice-container"> <!-- RECTO -->
<!-- Header --> <div class="page">
<div class="header"> <div class="invoice-container">
<h1>KELY SCOOTERS</h1> <!-- Header -->
<div class="header-info"> <div class="header">
<div class="header-left"> <h1>KELY SCOOTERS</h1>
<div>NIF: 401 840 5554</div> <div class="header-info">
<div>STAT: 46101 11 2024 00317</div> <div class="header-left">
</div> <div>NIF: 401 840 5554</div>
<div class="header-right"> <div>STAT: 46101 11 2024 00317</div>
<div>Contact: +261 34 27 946 35 / +261 34 07 079 69</div> </div>
<div>Antsakaviro en face WWF</div> <div class="header-right">
<div>Contact: +261 34 27 946 35 / +261 34 07 079 69</div>
<div>Antsakaviro en face WWF</div>
</div>
</div> </div>
</div> </div>
</div>
<!-- Invoice Title -->
<div class="invoice-title">
<div>
<h2>FACTURE</h2>
<div>Date: {$avanceDate}</div>
<div>N°: {$avanceNumber}CI 2025</div>
</div>
<div class="original-badge">DOIT ORIGINAL</div>
</div>
<!-- Customer Info -->
<div class="customer-info">
<div><strong>NOM:</strong> {$customerName} ({$customerPhone})</div>
<div><strong>CIN:</strong> {$customerCin}</div>
<div><strong>PC:</strong> {$grossAmount} Ar</div>
<div><strong>AVANCE:</strong> {$avanceAmount} Ar</div>
<div><strong>RAP:</strong> {$amountDue} Ar</div>
</div>
<!-- Product Table -->
<table class="product-table">
<thead>
<tr>
<th>MARQUE</th>
<th>N°MOTEUR</th>
<th>PUISSANCE</th>
<th>RAP (Ariary)</th>
</tr>
</thead>
<tbody>
<tr>
<td>{$marque}</td>
<td>{$numeroMoteur}</td>
<td>{$puissance}</td>
<td>{$amountDue}</td>
</tr>
</tbody>
</table>
<!-- Contract Section -->
<div class="contract-section">
<h3>FIFANEKENA ARA-BAROTRA (Réservations)</h3>
<p><strong>Ry mpanjifa hajaina,</strong></p>
<p>Natao ity fifanekena ity mba hialana amin'ny fivadihana hampitokisana amin'ny andaniny sy ankilany.</p>
<div class="contract-article">
<strong>Andininy faha-1: FAMANDRAHANA SY FANDOAVAM-BOLA</strong>
<p>Ny mpividy dia manao famandrahana amin'ny alalan'ny fandoavambola mihoatra ny 25 isan-jato amin'ny vidin'entana rehetra (avances).</p>
</div>
<div class="contract-article"> <!-- Invoice Title -->
<strong>Andininy faha-2: FANDOAVAM-BOLA REHEFA TONGA NY ENTANA (ARRIVAGE)</strong> <div class="invoice-title">
<p>Rehefa tonga ny moto/pieces dia tsy maintsy mandoa ny 50 isan-jato ny vidin'entana ny mpamandrika.</p> <div>
<p>Manana 15 andro kosa adoavana ny 25 isan-jato raha misy tsy fahafahana alohan'ny famoahana ny entana.</p> <h2>FACTURE</h2>
<div>Date: {$avanceDate}</div>
<div>N°: {$avanceNumber}CI 2025</div>
</div>
<div class="original-badge">DOIT ORIGINAL</div>
</div> </div>
<div class="contract-article"> <!-- Customer Info -->
<strong>Andininy faha-3: FAMERENANA VOLA</strong> <div class="customer-info">
<p>Raha toa ka misy antony tsy hakana ny entana indray dia tsy mamerina ny vola efa voaloha (avance) ny société.</p> <div><strong>NOM:</strong> {$customerName} ({$customerPhone})</div>
<div><strong>CIN:</strong> {$customerCin}</div>
<div><strong>PC:</strong> {$grossAmount} Ar</div>
<div><strong>AVANCE:</strong> {$avanceAmount} Ar</div>
<div><strong>RAP:</strong> {$amountDue} Ar</div>
</div> </div>
<div class="contract-article"> <!-- Product Table -->
<strong>Andininy faha-4: FEPETRA FANAMPINY</strong> <table class="product-table">
<ul style="margin-left: 20px;"> <thead>
<li>Tsy misafidy raha toa ka mamafa no ifanarahana.</li> <tr>
<li>Tsy azo atao ny mamerina ny entana efa nofandrahana.</li> <th>MARQUE</th>
<li>Tsy azo atao ny manakalo ny entana efa nofandrahana.</li> <th>N°MOTEUR</th>
</ul> <th>PUISSANCE</th>
</div> <th>RAP (Ariary)</th>
</tr>
</thead>
<tbody>
<tr>
<td>{$marque}</td>
<td>{$numeroMoteur}</td>
<td>{$puissance}</td>
<td>{$amountDue}</td>
</tr>
</tbody>
</table>
</div> </div>
</div>
<!-- Signatures -->
<div class="signature-section"> <!-- VERSO -->
<div class="signature-box"> <div class="page">
<p>NY MPAMANDRIKA</p> <div class="invoice-container">
<div style="border-top: 1px solid #000; padding-top: 5px;">Signature</div>
</div>
<div class="signature-box"> <div class="invoice-title">
<p>NY MPIVAROTRA</p> <div>
<div style="border-top: 1px solid #000; padding-top: 5px;"> <h2>CONDITIONS GÉNÉRALES</h2>
<strong>KELY SCOOTERS</strong><br> <div>Date: {$avanceDate}</div>
NIF: 401 840 5554 <div>N°: {$avanceNumber}CI 2025</div>
<div class="verso-content">
<!-- Contract Section -->
<div class="contract-section">
<h3>FIFANEKENA ARA-BAROTRA (Réservations)</h3>
<p><strong>Ry mpanjifa hajaina,</strong></p>
<p>Natao ity fifanekena ity mba hialana amin'ny fivadihana hampitokisana amin'ny andaniny sy ankilany.</p>
<div class="contract-article">
<strong>Andininy faha-1: FAMANDRAHANA SY FANDOAVAM-BOLA</strong>
<p>Ny mpividy dia manao famandrahana amin'ny alalan'ny fandoavambola mihoatra ny 25 isan-jato amin'ny vidin'entana rehetra (avances).</p>
</div>
<div class="contract-article">
<strong>Andininy faha-2: FANDOAVAM-BOLA REHEFA TONGA NY ENTANA (ARRIVAGE)</strong>
<p>Rehefa tonga ny moto/pieces dia tsy maintsy mandoa ny 50 isan-jato ny vidin'entana ny mpamandrika.</p>
<p>Manana 15 andro kosa adoavana ny 25 isan-jato raha misy tsy fahafahana alohan'ny famoahana ny entana.</p>
</div>
<div class="contract-article">
<strong>Andininy faha-3: FAMERENANA VOLA</strong>
<p>Raha toa ka misy antony tsy hakana ny entana indray dia tsy mamerina ny vola efa voaloha (avance) ny société.</p>
</div>
<div class="contract-article">
<strong>Andininy faha-4: FEPETRA FANAMPINY</strong>
<ul style="margin-left: 20px;">
<li>Tsy misafidy raha toa ka mamafa no ifanarahana.</li>
<li>Tsy azo atao ny mamerina ny entana efa nofandrahana.</li>
<li>Tsy azo atao ny manakalo ny entana efa nofandrahana.</li>
</ul>
</div>
</div>
<!-- Additional space for notes -->
<div style="margin-top: 20px; padding: 10px; border: 1px solid #000; flex: 1;">
<strong>OBSERVATIONS / NOTES:</strong>
<div style="height: 100px; margin-top: 10px;"></div>
</div>
<!-- Signatures for verso -->
<div class="signature-section">
<div class="signature-box">
<p>NY MPAMANDRIKA</p>
<div style="border-top: 1px solid #000; padding-top: 5px;">Signature</div>
</div>
<div class="signature-box">
<p>NY MPIVAROTRA</p>
<div style="border-top: 1px solid #000; padding-top: 5px;">
<strong>KELY SCOOTERS</strong><br>
NIF: 401 840 5554
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -1877,7 +1919,6 @@ private function generatePrintableInvoiceHTML($avance, $productName, $productDet
</html> </html>
HTML; HTML;
} }
/** /**
* ✅ NOUVELLE MÉTHODE : Traiter manuellement les avances expirées * ✅ NOUVELLE MÉTHODE : Traiter manuellement les avances expirées
* URL: /avances/processExpiredAvances * URL: /avances/processExpiredAvances

1165
app/Controllers/OrderController.php

File diff suppressed because it is too large

49
app/Models/OrderItems.php

@ -5,35 +5,23 @@ namespace App\Models;
use CodeIgniter\Model; use CodeIgniter\Model;
use DateTime; use DateTime;
/**
* table pivot
*/
class OrderItems extends Model class OrderItems extends Model
{ {
/**
* table name
* @var string
*/
protected $table = 'orders_item'; protected $table = 'orders_item';
protected $allowedFields = ['order_id', 'product_id', 'qty', 'rate' , 'amount' ]; protected $allowedFields = ['order_id', 'product_id', 'puissance', 'rate', 'amount'];
public function insertOrderItem($data) public function insertOrderItem($data)
{ {
return $this->insert($data); return $this->insert($data);
} }
/**
* get the orders item data
* @param mixed $order_id
* @return array|bool
*/
public function getOrdersItemData($order_id = null) public function getOrdersItemData($order_id = null)
{ {
if (!$order_id) { if (!$order_id) {
return false; return false;
} }
return $this->where('order_id', $order_id)->findAll(); // Get items of a specific order return $this->where('order_id', $order_id)->findAll();
} }
public function getAllSoldProductToday() { public function getAllSoldProductToday() {
@ -57,27 +45,22 @@ class OrderItems extends Model
} }
public function updateOrderItem(int $id, array $data) public function updateOrderItem(int $id, array $data)
{ {
return $this->where('order_id', $id) return $this->where('order_id', $id)
->set($data) ->set($data)
->update(); ->update();
}
public function getProductIds(array $orderIds): array
{
if (empty($orderIds)) {
return [];
} }
$items = $this->select('product_id') public function getProductIds(array $orderIds): array
->whereIn('order_id', $orderIds) {
->findAll(); if (empty($orderIds)) {
return [];
// Extrait la colonne product_id }
return array_column($items, 'product_id');
}
$items = $this->select('product_id')
->whereIn('order_id', $orderIds)
->findAll();
return array_column($items, 'product_id');
}
} }

39
app/Models/Orders.php

@ -196,47 +196,43 @@ class Orders extends Model
$orderItemModel = new OrderItems(); $orderItemModel = new OrderItems();
$productModel = new Products(); $productModel = new Products();
// ✅ RÉCUPÉRER LE TABLEAU DES PUISSANCES
$puissances = $data['puissance'] ?? [];
// Loop through products and insert order items // Loop through products and insert order items
$count_product = count($post); $count_product = count($post);
for ($x = 0; $x < $count_product; $x++) { for ($x = 0; $x < $count_product; $x++) {
// ✅ AJOUT DE LA PUISSANCE
$items = [ $items = [
'order_id' => $order_id, 'order_id' => $order_id,
'product_id' => $post[$x], 'product_id' => $post[$x],
'rate' => $data['rate_value'][$x], 'rate' => $data['rate_value'][$x],
'qty' =>1, 'qty' => 1,
'amount' => $data['amount_value'][$x], 'amount' => $data['amount_value'][$x],
'puissance' => $puissances[$x] ?? 1, // ✅ CORRECTION ICI
]; ];
$orderItemModel->insert($items); $orderItemModel->insert($items);
// Insert order item // Decrease stock for the product
// // Decrease stock for the product
$product_data = $productModel->find($post[$x]); $product_data = $productModel->find($post[$x]);
if((int)$data['paid_status'] == 1){ if((int)$data['paid_status'] == 1){
if ($product_data) {
if ($product_data) { $product_sold = true;
$product_sold = true; $productModel->update($post[$x], ['product_sold' => $product_sold]);
} else {
// Update product stock $product_sold = false;
$productModel->update($post[$x], ['product_sold' => $product_sold]); $productModel->update($post[$x], ['product_sold' => $product_sold]);
} }
else{
$product_sold = false;
$productModel->update($post[$x], ['product_sold' => $product_sold]);
} }
} }
} return $order_id;
return $order_id; // Return order ID if everything is successful
} catch (\Exception $e) { } catch (\Exception $e) {
// Log the exception for debugging (optional)
log_message('error', 'Error creating order: ' . $e->getMessage()); log_message('error', 'Error creating order: ' . $e->getMessage());
return false;
return false; // Return false if an error occurs
} }
} }
/** /**
* count order item * count order item
* @param int $order_id * @param int $order_id
@ -284,6 +280,7 @@ class Orders extends Model
'order_id' => $id, 'order_id' => $id,
'product_id' => $data['product'][$x], 'product_id' => $data['product'][$x],
'rate' => $data['rate_value'][$x], 'rate' => $data['rate_value'][$x],
'puissance' => $data['puissance'][$x],
'amount' => $data['amount_value'][$x], 'amount' => $data['amount_value'][$x],
]; ];

80
app/Views/orders/createbyid.php

@ -114,12 +114,16 @@
</div> </div>
</div> </div>
<br /> <br /> <br /> <br />
<!-- ✅ TABLEAU AVEC COLONNE PUISSANCE -->
<table class="table table-bordered" id="product_info_table"> <table class="table table-bordered" id="product_info_table">
<thead> <thead>
<tr> <tr>
<th style="width:50%">Produit</th> <th style="width:40%">Produit</th>
<th style="width:10%">Prix unitaire</th> <th style="width:15%">Puissance (CC)</th>
<th style="width:15%">Prix unitaire</th>
<th style="width:20%">Montant</th> <th style="width:20%">Montant</th>
<th style="width:10%"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -129,31 +133,46 @@
id="product_1" name="product[]" style="width:100%;" id="product_1" name="product[]" style="width:100%;"
onchange="getProductData(1)" required> onchange="getProductData(1)" required>
<option value="<?= $products['id'] ?>"> <option value="<?= $products['id'] ?>">
<?= $products['sku'] . ' | ' . $products['name'] . ' | ' . $products['numero_de_moteur'] . ' | ' . $products['puissance'] ?> <?= $products['sku'] . ' | ' . $products['name'] . ' | ' . $products['numero_de_moteur'] ?>
</option> </option>
</select> </select>
</td> </td>
<!-- ✅ COLONNE PUISSANCE -->
<td>
<input type="number" name="puissance[]" id="puissance_1"
class="form-control" placeholder="CC"
value="<?= esc($products['puissance'] ?? '1') ?>"
min="1" autocomplete="off">
</td>
<td> <td>
<input type="text" name="rate[]" id="rate_1" class="form-control" disabled <input type="text" name="rate[]" id="rate_1" class="form-control" disabled
autocomplete="off" value="<?= $pu ?>" min="0"> autocomplete="off" value="<?= esc($pu) ?>" min="0">
<input type="hidden" name="rate_value[]" value="<?= $pu ?>" <input type="hidden" name="rate_value[]" id="rate_value_1"
id="rate_value_1" class="form-control" autocomplete="off"> value="<?= esc($pu) ?>" class="form-control" autocomplete="off">
<input type="hidden" id="min_price_1" name="min_price[]" value=""> <input type="hidden" id="min_price_1" name="min_price[]" value="">
</td> </td>
<td> <td>
<input type="text" name="amount[]" id="amount_1" class="form-control" <input type="text" name="amount[]" id="amount_1" class="form-control"
disabled autocomplete="off" min="0"> disabled autocomplete="off" min="0">
<input type="hidden" name="amount_value[]" id="amount_value_1" <input type="hidden" name="amount_value[]" id="amount_value_1"
class="form-control" autocomplete="off"> class="form-control" autocomplete="off">
</td> </td>
<td><button type="button" class="btn btn-default" onclick="removeRow('1')"><i
class="fa fa-close"></i></button></td> <td>
<button type="button" class="btn btn-default" onclick="removeRow('1')">
<i class="fa fa-close"></i>
</button>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<input type="hidden" name="qty[]" value="1" id="qty_1" min="1"
class="form-control valueqty" required onkeyup="getTotal(1)"> <!-- ✅ Champ qty caché (toujours = 1) -->
<input type="hidden" name="qty[]" value="1" id="qty_1" class="form-control">
<br /> <br /> <br /> <br />
<div class="col-md-6 col-xs-12 pull pull-right"> <div class="col-md-6 col-xs-12 pull pull-right">
<div class="form-group"> <div class="form-group">
@ -186,6 +205,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="box-footer"> <div class="box-footer">
<input type="hidden" name="service_charge_rate" <input type="hidden" name="service_charge_rate"
value="<?php echo $company_data['service_charge_value'] ?>" autocomplete="off"> value="<?php echo $company_data['service_charge_value'] ?>" autocomplete="off">
@ -210,7 +230,6 @@
function validatePositiveNumber(input) { function validatePositiveNumber(input) {
let value = parseFloat(input.value); let value = parseFloat(input.value);
// Si la valeur est négative ou NaN, on la remet à 0
if (isNaN(value) || value < 0) { if (isNaN(value) || value < 0) {
input.value = ''; input.value = '';
return false; return false;
@ -236,7 +255,6 @@
let prixDemande = parseFloat(input.value); let prixDemande = parseFloat(input.value);
let prixAffiche = parseFloat($('#gross_amount').val()) || 0; let prixAffiche = parseFloat($('#gross_amount').val()) || 0;
// Vérifier si négatif
if (isNaN(prixDemande) || prixDemande < 0) { if (isNaN(prixDemande) || prixDemande < 0) {
input.value = ''; input.value = '';
showDiscountError('Le prix demandé ne peut pas être négatif.'); showDiscountError('Le prix demandé ne peut pas être négatif.');
@ -244,7 +262,6 @@
return false; return false;
} }
// Vérifier si supérieur au prix affiché
if (prixDemande > prixAffiche) { if (prixDemande > prixAffiche) {
showDiscountError('Le prix demandé (' + prixDemande.toFixed(2) + ') ne peut pas être supérieur au prix affiché (' + prixAffiche.toFixed(2) + ').'); showDiscountError('Le prix demandé (' + prixDemande.toFixed(2) + ') ne peut pas être supérieur au prix affiché (' + prixAffiche.toFixed(2) + ').');
input.value = prixAffiche; input.value = prixAffiche;
@ -253,14 +270,12 @@
return false; return false;
} }
// Si tout est valide, masquer l'erreur
hideDiscountError(); hideDiscountError();
return true; return true;
} }
// ✅ Fonction pour empêcher la saisie de caractères négatifs // ✅ Fonction pour empêcher la saisie de caractères négatifs
function preventNegativeInput(e) { function preventNegativeInput(e) {
// Empêche la saisie du signe moins (-)
if (e.key === '-' || e.key === 'e' || e.key === 'E' || e.key === '+') { if (e.key === '-' || e.key === 'e' || e.key === 'E' || e.key === '+') {
e.preventDefault(); e.preventDefault();
return false; return false;
@ -268,7 +283,12 @@
} }
$(document).ready(function () { $(document).ready(function () {
// ✅ INITIALISATION : Calculer le total au chargement
getTotal(1); getTotal(1);
// ✅ INITIALISATION : S'assurer que rate_value_1 est bien rempli
$("#rate_value_1").val($("#rate_1").val());
$(".select_group").select2(); $(".select_group").select2();
$("#mainOrdersNav").addClass('active'); $("#mainOrdersNav").addClass('active');
@ -295,7 +315,6 @@
// Bloquer la soumission du formulaire // Bloquer la soumission du formulaire
$('form').on('submit', function(e) { $('form').on('submit', function(e) {
// Vérifier tous les champs numériques avant soumission
let hasNegative = false; let hasNegative = false;
$('.numeric-input, input[type="number"]').each(function() { $('.numeric-input, input[type="number"]').each(function() {
if (parseFloat($(this).val()) < 0) { if (parseFloat($(this).val()) < 0) {
@ -332,11 +351,14 @@
'<select class="form-control select_group product" data-row-id="' + row_id + '" id="product_' + row_id + '" name="product[]" style="width:100%;" onchange="getProductData(' + row_id + ')">' + '<select class="form-control select_group product" data-row-id="' + row_id + '" id="product_' + row_id + '" name="product[]" style="width:100%;" onchange="getProductData(' + row_id + ')">' +
'<option value=""></option>'; '<option value=""></option>';
$.each(response, function (index, value) { $.each(response, function (index, value) {
html += '<option value="' + value.id + '">' + value.sku + ' | ' + value.name + ' | ' + value.numero_de_moteur + ' | ' + value.puissance + '</option>'; // ✅ NE PLUS AFFICHER LA PUISSANCE DANS LE SELECT
html += '<option value="' + value.id + '">' + value.sku + ' | ' + value.name + ' | ' + value.numero_de_moteur + '</option>';
}); });
html += '</select>' + html += '</select>' +
'</td>' + '</td>' +
// ✅ COLONNE PUISSANCE
'<td><input type="number" name="puissance[]" id="puissance_' + row_id + '" class="form-control" placeholder="CC" min="1" value="1" autocomplete="off"></td>' +
'<td><input type="text" name="rate[]" id="rate_' + row_id + '" class="form-control numeric-input" disabled min="0"><input type="hidden" name="rate_value[]" id="rate_value_' + row_id + '" class="form-control"><input type="hidden" id="min_price_' + row_id + '" name="min_price[]" value=""></td>' + '<td><input type="text" name="rate[]" id="rate_' + row_id + '" class="form-control numeric-input" disabled min="0"><input type="hidden" name="rate_value[]" id="rate_value_' + row_id + '" class="form-control"><input type="hidden" id="min_price_' + row_id + '" name="min_price[]" value=""></td>' +
'<td><input type="text" name="amount[]" id="amount_' + row_id + '" class="form-control numeric-input" disabled min="0"><input type="hidden" name="amount_value[]" id="amount_value_' + row_id + '" class="form-control"></td>' + '<td><input type="text" name="amount[]" id="amount_' + row_id + '" class="form-control numeric-input" disabled min="0"><input type="hidden" name="amount_value[]" id="amount_value_' + row_id + '" class="form-control"></td>' +
'<td><button type="button" class="btn btn-default" onclick="removeRow(\'' + row_id + '\')"><i class="fa fa-close"></i></button></td>' + '<td><button type="button" class="btn btn-default" onclick="removeRow(\'' + row_id + '\')"><i class="fa fa-close"></i></button></td>' +
@ -362,7 +384,6 @@
var rate = Number($("#rate_value_" + row).val()); var rate = Number($("#rate_value_" + row).val());
var qty = Number($("#qty_" + row).val()); var qty = Number($("#qty_" + row).val());
// ✅ Vérifier que les valeurs sont positives
if (rate < 0) rate = 0; if (rate < 0) rate = 0;
if (qty < 0) qty = 0; if (qty < 0) qty = 0;
@ -378,14 +399,14 @@
} }
} }
// get the product information from the server // ✅ GET PRODUCT DATA - Récupère prix + puissance
function getProductData(row_id) { function getProductData(row_id) {
var product_id = $("#product_" + row_id).val(); var product_id = $("#product_" + row_id).val();
if (product_id == "") { if (product_id == "") {
$("#rate_" + row_id).val(""); $("#rate_" + row_id).val("");
$("#rate_value_" + row_id).val(""); $("#rate_value_" + row_id).val("");
$("#min_price_" + row_id).val(""); $("#min_price_" + row_id).val("");
$("#qty_" + row_id).val(""); $("#puissance_" + row_id).val("1");
$("#amount_" + row_id).val(""); $("#amount_" + row_id).val("");
$("#amount_value_" + row_id).val(""); $("#amount_value_" + row_id).val("");
@ -398,7 +419,8 @@
}, },
dataType: 'json', dataType: 'json',
success: function (response) { success: function (response) {
// ✅ S'assurer que les prix ne sont pas négatifs console.log('✅ Response:', response); // Debug
var prixVente = parseFloat(response.prix_vente) || 0; var prixVente = parseFloat(response.prix_vente) || 0;
var prixMinimal = parseFloat(response.prix_minimal) || 0; var prixMinimal = parseFloat(response.prix_minimal) || 0;
@ -409,8 +431,12 @@
$("#rate_value_" + row_id).val(prixVente); $("#rate_value_" + row_id).val(prixVente);
$("#min_price_" + row_id).val(prixMinimal); $("#min_price_" + row_id).val(prixMinimal);
// ✅ REMPLIR LA PUISSANCE
var puissanceValue = response.puissance || '1';
console.log('✅ Puissance extraite:', puissanceValue); // Debug
$("#puissance_" + row_id).val(puissanceValue);
$("#qty_" + row_id).val(1); $("#qty_" + row_id).val(1);
$("#qty_value_" + row_id).val(1);
var total = prixVente * 1; var total = prixVente * 1;
total = total.toFixed(2); total = total.toFixed(2);
@ -436,7 +462,6 @@
count = count.substring(4); count = count.substring(4);
var amount = Number($("#amount_" + count).val()); var amount = Number($("#amount_" + count).val());
// ✅ Vérifier que le montant n'est pas négatif
if (amount < 0) amount = 0; if (amount < 0) amount = 0;
totalSubAmount = Number(totalSubAmount) + amount; totalSubAmount = Number(totalSubAmount) + amount;
} }
@ -464,7 +489,6 @@
totalAmount = totalAmount.toFixed(2); totalAmount = totalAmount.toFixed(2);
var discount = Number($("#discount").val()) || 0; var discount = Number($("#discount").val()) || 0;
// ✅ S'assurer que le rabais n'est pas négatif
if (discount < 0) { if (discount < 0) {
discount = 0; discount = 0;
$("#discount").val(''); $("#discount").val('');
@ -472,7 +496,6 @@
if (discount) { if (discount) {
var grandTotal = Number(totalAmount) - Number(discount); var grandTotal = Number(totalAmount) - Number(discount);
// ✅ S'assurer que le total n'est pas négatif
if (grandTotal < 0) grandTotal = 0; if (grandTotal < 0) grandTotal = 0;
grandTotal = grandTotal.toFixed(2); grandTotal = grandTotal.toFixed(2);
$("#net_amount").val(grandTotal); $("#net_amount").val(grandTotal);
@ -487,7 +510,6 @@
function checkMinimalPrice() { function checkMinimalPrice() {
var discount = Number($("#discount").val()) || 0; var discount = Number($("#discount").val()) || 0;
// ✅ Vérifier que le rabais n'est pas négatif
if (discount < 0) { if (discount < 0) {
alert("Le prix demandé ne peut pas être négatif."); alert("Le prix demandé ne peut pas être négatif.");
$("#discount").val(''); $("#discount").val('');
@ -495,7 +517,6 @@
return false; return false;
} }
// Si pas de rabais, pas de vérification nécessaire
if (discount === 0) return true; if (discount === 0) return true;
var tableProductLength = $("#product_info_table tbody tr").length; var tableProductLength = $("#product_info_table tbody tr").length;
@ -507,7 +528,6 @@
var rowId = $(tr).attr('id').replace('row_', ''); var rowId = $(tr).attr('id').replace('row_', '');
var minPrice = Number($("#min_price_" + rowId).val()) || 0; var minPrice = Number($("#min_price_" + rowId).val()) || 0;
// ✅ Le rabais devient le prix de vente
if (minPrice > 0 && discount < minPrice) { if (minPrice > 0 && discount < minPrice) {
error = true; error = true;
var productText = $("#product_" + rowId + " option:selected").text(); var productText = $("#product_" + rowId + " option:selected").text();
@ -529,7 +549,7 @@
subAmount(); subAmount();
} }
// new area of javascript in the order // ✅ INITIALISATION AU CHARGEMENT
const quantity = document.getElementById('qty_1') const quantity = document.getElementById('qty_1')
const rates = document.getElementById('rate_1') const rates = document.getElementById('rate_1')
const amount = document.getElementById('amount_1') const amount = document.getElementById('amount_1')
@ -549,13 +569,11 @@
net_amount_value.value = (gross_amount_value.value - remise.value); net_amount_value.value = (gross_amount_value.value - remise.value);
remise.addEventListener('input', function () { remise.addEventListener('input', function () {
// ✅ Validation du prix demandé vs prix affiché
if (validatePrixDemande(this)) { if (validatePrixDemande(this)) {
var discountValue = parseFloat(this.value) || 0; var discountValue = parseFloat(this.value) || 0;
var grossValue = parseFloat(gross_amount_value.value) || 0; var grossValue = parseFloat(gross_amount_value.value) || 0;
var netValue = grossValue - discountValue; var netValue = grossValue - discountValue;
// ✅ S'assurer que le net amount n'est pas négatif
if (netValue < 0) netValue = 0; if (netValue < 0) netValue = 0;
net_amount.value = netValue.toFixed(2); net_amount.value = netValue.toFixed(2);

676
app/Views/orders/edit.php

@ -1,6 +1,4 @@
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper"> <div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header"> <section class="content-header">
<h1> <h1>
Gérer les Gérer les
@ -12,78 +10,51 @@
</ol> </ol>
</section> </section>
<!-- Main content -->
<section class="content"> <section class="content">
<!-- Small boxes (Stat box) -->
<div class="row"> <div class="row">
<div class="col-md-12 col-xs-12"> <div class="col-md-12 col-xs-12">
<div id="messages"></div> <div id="messages"></div>
<?php if (session()->getFlashdata('success')): ?> <?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success alert-dismissible" role="alert"> <div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<?php echo session()->getFlashdata('success'); ?> <?php echo session()->getFlashdata('success'); ?>
</div> </div>
<?php elseif (session()->getFlashdata('error')): ?> <?php elseif (session()->getFlashdata('error')): ?>
<div class="alert alert-danger alert-dismissible" role="alert"> <div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<?php echo session()->getFlashdata('error'); ?> <?php echo session()->getFlashdata('error'); ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if ($errors = session()->getFlashdata('errors')): ?> <?php if ($errors = session()->getFlashdata('errors')): ?>
<div class="alert alert-danger alert-dismissible" role="alert"> <div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
<?php if (is_array($errors)): ?> <?php if (is_array($errors)): ?>
<ul> <ul>
<?php foreach ($errors as $error): ?> <?php foreach ($errors as $error): ?>
<li><?= esc($error) ?></li> <li><?= esc($error) ?></li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
<?php else: ?> <?php else: ?>
<?= esc($errors) ?> <?= esc($errors) ?>
<?php endif; ?> <?php endif; ?>
</div> </div>
<?php endif; ?>
<?php
// ✅ VÉRIFIER SI LA COMMANDE EST MODIFIABLE
// Seuls les statuts 1 (Validé) et 3 (Validé et Livré) sont NON modifiables
$is_editable = isset($is_editable) ? $is_editable : true;
$paid_status = $order_data['order']['paid_status'] ?? 2;
?>
<?php if (!$is_editable): ?>
<!-- ✅ ALERTE SI NON MODIFIABLE -->
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<strong><i class="fa fa-lock"></i> Cette commande ne peut plus être modifiée</strong><br>
Elle a été <?php echo ($paid_status == 1) ? 'validée' : 'validée et livrée'; ?>.
Vous pouvez uniquement consulter les informations.
</div>
<?php endif; ?> <?php endif; ?>
<div class="box"> <div class="box">
<div class="box-header"> <div class="box-header">
<h3 class="box-title"> <h3 class="box-title">Mise à jour de commande</h3>
<?php echo $is_editable ? 'Mise à jour de commande' : 'Consultation de commande'; ?>
</h3>
</div> </div>
<!-- /.box-header -->
<form role="form" <form role="form" action="<?php base_url('orders/create') ?>" method="post" class="form-horizontal">
action="<?php base_url('orders/create') ?>"
method="post"
class="form-horizontal"
<?php echo !$is_editable ? 'onsubmit="return false;"' : ''; ?>>
<div class="box-body"> <div class="box-body">
<div class="form-group"> <div class="form-group">
@ -98,7 +69,7 @@
<div class="form-group"> <div class="form-group">
<label for="types" class="col-sm-5 control-label" style="text-align:left;">Types</label> <label for="types" class="col-sm-5 control-label" style="text-align:left;">Types</label>
<div class="col-sm-7"> <div class="col-sm-7">
<select name="" id="typesCommande" class="form-control" <?php echo !$is_editable ? 'disabled' : ''; ?>> <select name="" id="typesCommande" class="form-control">
<option value="1">Facture</option> <option value="1">Facture</option>
<option value="2">Bon de Livraison & Facture</option> <option value="2">Bon de Livraison & Facture</option>
<option value="3">Bon de Livraison</option> <option value="3">Bon de Livraison</option>
@ -109,56 +80,28 @@
<div class="form-group"> <div class="form-group">
<label for="customer_name" class="col-sm-5 control-label" style="text-align:left;">Nom du client</label> <label for="customer_name" class="col-sm-5 control-label" style="text-align:left;">Nom du client</label>
<div class="col-sm-7"> <div class="col-sm-7">
<input type="text" <input type="text" class="form-control" id="customer_name" name="customer_name" placeholder="Enter Customer Name" value="<?php echo $order_data['order']['customer_name'] ?>" autocomplete="off" />
class="form-control"
id="customer_name"
name="customer_name"
placeholder="Enter Customer Name"
value="<?php echo $order_data['order']['customer_name'] ?>"
autocomplete="off"
<?php echo !$is_editable ? 'disabled readonly' : ''; ?> />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="gross_amount" class="col-sm-5 control-label" style="text-align:left;">Adresse du client</label> <label for="gross_amount" class="col-sm-5 control-label" style="text-align:left;">Adresse du client</label>
<div class="col-sm-7"> <div class="col-sm-7">
<input type="text" <input type="text" class="form-control" id="customer_address" name="customer_address" placeholder="Enter Customer Address" value="<?php echo $order_data['order']['customer_address'] ?>" autocomplete="off">
class="form-control"
id="customer_address"
name="customer_address"
placeholder="Enter Customer Address"
value="<?php echo $order_data['order']['customer_address'] ?>"
autocomplete="off"
<?php echo !$is_editable ? 'disabled readonly' : ''; ?>>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="gross_amount" class="col-sm-5 control-label" style="text-align:left;">Téléphone du client</label> <label for="gross_amount" class="col-sm-5 control-label" style="text-align:left;">Téléphone du client</label>
<div class="col-sm-7"> <div class="col-sm-7">
<input type="text" <input type="text" class="form-control" id="customer_phone" name="customer_phone" placeholder="Enter Customer Phone" value="<?php echo $order_data['order']['customer_phone'] ?>" autocomplete="off">
class="form-control"
id="customer_phone"
name="customer_phone"
placeholder="Enter Customer Phone"
value="<?php echo $order_data['order']['customer_phone'] ?>"
autocomplete="off"
<?php echo !$is_editable ? 'disabled readonly' : ''; ?>>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="gross_amount" class="col-sm-5 control-label" style="text-align:left;">CIN du client</label> <label for="gross_amount" class="col-sm-5 control-label" style="text-align:left;">CIN du client</label>
<div class="col-sm-7"> <div class="col-sm-7">
<input type="text" <input type="text" class="form-control" id="customer_cin" name="customer_cin" placeholder="Enter Customer CIN" value="<?php echo $order_data['order']['customer_cin'] ?>" autocomplete="off">
class="form-control"
id="customer_cin"
name="customer_cin"
placeholder="Enter Customer CIN"
value="<?php echo $order_data['order']['customer_cin'] ?>"
autocomplete="off"
<?php echo !$is_editable ? 'disabled readonly' : ''; ?>>
</div> </div>
</div> </div>
</div> </div>
@ -168,88 +111,72 @@
<thead> <thead>
<tr> <tr>
<th style="width:50%">Produit</th> <th style="width:50%">Produit</th>
<th style="width:10%">Quantité</th> <th style="width:15%">Puissance (CC)</th>
<th style="width:10%">Prix unitaire</th> <th style="width:10%">Prix unitaire</th>
<th style="width:20%">Montant</th> <th style="width:20%">Montant</th>
<th style="width:10%"> <th style="width:10%"><button type="button" id="add_row" class="btn btn-default"><i class="fa fa-plus"></i></button></th>
<?php if ($is_editable): ?>
<button type="button" id="add_row" class="btn btn-default"><i class="fa fa-plus"></i></button>
<?php endif; ?>
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php if (isset($order_data['order_item'])): ?> <?php if (isset($order_data['order_item'])): ?>
<?php $x = 1; ?> <?php $x = 1; ?>
<?php foreach ($order_data['order_item'] as $key => $val): ?> <?php foreach ($order_data['order_item'] as $key => $val): ?>
<tr id="row_<?php echo $x; ?>"> <tr id="row_<?php echo $x; ?>">
<td> <td>
<select class="form-control select_group product" <select class="form-control select_group product" data-row-id="row_<?php echo $x; ?>"
data-row-id="row_<?php echo $x; ?>" id="product_<?php echo $x; ?>" name="product[]" style="width:100%;"
id="product_<?php echo $x; ?>" onchange="getProductData(<?php echo $x; ?>)" required>
name="product[]" <option value=""></option>
style="width:100%;" <?php foreach ($products as $k => $v): ?>
onchange="getProductData(<?php echo $x; ?>)" <option value="<?php echo $v['id'] ?>"
<?php echo !$is_editable ? 'disabled' : 'required'; ?>> <?php if ($val['product_id'] == $v['id']) { echo "selected='selected'"; } ?>>
<option value=""></option> <?php
<?php foreach ($products as $k => $v): ?> echo $v['sku'] . ' | ' . $v['name'];
<option value="<?php echo $v['id'] ?>" <?php if ($val['product_id'] == $v['id']) { echo "selected='selected'"; } ?>><?php echo $v['name'] ?></option> if (!empty($v['numero_de_moteur'])) {
<?php endforeach ?> echo ' | ' . $v['numero_de_moteur'];
</select> }
</td> ?>
<td> </option>
<input type="number" <?php endforeach ?>
name="qty[]" </select>
id="qty_<?php echo $x; ?>" </td>
class="form-control"
onkeyup="getTotal(<?php echo $x; ?>)" <!-- ✅ COLONNE PUISSANCE VISIBLE -->
value="<?php echo $val['qty'] ?>" <td>
autocomplete="off" <input type="number" name="puissance[]" id="puissance_<?php echo $x; ?>"
<?php echo !$is_editable ? 'disabled readonly' : 'required'; ?>> class="form-control" placeholder="Puissance"
</td> value="<?php echo esc($val['puissance'] ?? '1') ?>"
<td> autocomplete="off" min="1">
<input type="text" </td>
name="rate[]"
id="rate_<?php echo $x; ?>" <td>
class="form-control" <input type="text" name="rate[]" id="rate_<?php echo $x; ?>"
disabled class="form-control" disabled
value="<?php echo $val['rate'] ?>" value="<?php echo esc($val['rate']) ?>" autocomplete="off">
autocomplete="off"> <input type="hidden" name="rate_value[]" id="rate_value_<?php echo $x; ?>"
<input type="hidden" class="form-control" value="<?php echo esc($val['rate']) ?>" autocomplete="off">
name="rate_value[]" </td>
id="rate_value_<?php echo $x; ?>"
class="form-control" <td>
value="<?php echo $val['rate'] ?>" <input type="text" name="amount[]" id="amount_<?php echo $x; ?>"
autocomplete="off"> class="form-control" disabled
</td> value="<?php echo esc($val['amount']) ?>" autocomplete="off">
<td> <input type="hidden" name="amount_value[]" id="amount_value_<?php echo $x; ?>"
<input type="text" class="form-control" value="<?php echo esc($val['amount']) ?>" autocomplete="off">
name="amount[]" </td>
id="amount_<?php echo $x; ?>"
class="form-control" <td>
disabled <button type="button" class="btn btn-default"
value="<?php echo $val['amount'] ?>" onclick="removeRow('<?php echo $x; ?>')">
autocomplete="off"> <i class="fa fa-close"></i>
<input type="hidden" </button>
name="amount_value[]" </td>
id="amount_value_<?php echo $x; ?>" </tr>
class="form-control" <?php $x++; ?>
value="<?php echo $val['amount'] ?>" <?php endforeach; ?>
autocomplete="off"> <?php endif; ?>
</td> </tbody>
<td>
<?php if ($is_editable): ?>
<button type="button" class="btn btn-default" onclick="removeRow('<?php echo $x; ?>')">
<i class="fa fa-close"></i>
</button>
<?php endif; ?>
</td>
</tr>
<?php $x++; ?>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table> </table>
<br /> <br /> <br /> <br />
@ -259,75 +186,29 @@
<div class="form-group"> <div class="form-group">
<label for="gross_amount" class="col-sm-5 control-label">Prix affiché</label> <label for="gross_amount" class="col-sm-5 control-label">Prix affiché</label>
<div class="col-sm-7"> <div class="col-sm-7">
<input type="text" <input type="text" class="form-control" id="gross_amount" name="gross_amount" disabled value="<?php echo $order_data['order']['gross_amount'] ?>" autocomplete="off">
class="form-control" <input type="hidden" class="form-control" id="gross_amount_value" name="gross_amount_value" value="<?php echo $order_data['order']['gross_amount'] ?>" autocomplete="off">
id="gross_amount"
name="gross_amount"
disabled
value="<?php echo $order_data['order']['gross_amount'] ?>"
autocomplete="off">
<input type="hidden"
class="form-control"
id="gross_amount_value"
name="gross_amount_value"
value="<?php echo $order_data['order']['gross_amount'] ?>"
autocomplete="off">
</div>
</div>
<!-- ✅ ALERTE VISUELLE INTÉGRÉE -->
<div id="price_alert" style="display: none; margin-bottom: 15px;">
<div class="col-sm-offset-5 col-sm-7">
<div style="background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; padding: 10px 15px; border-radius: 4px; animation: slideDown 0.3s ease-out;">
<i class="fa fa-exclamation-triangle" style="margin-right: 8px;"></i>
<strong>Attention !</strong> <span id="price_alert_message"></span>
</div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="discount" class="col-sm-5 control-label">Prix demandé</label> <label for="discount" class="col-sm-5 control-label">Prix demandé</label>
<div class="col-sm-7"> <div class="col-sm-7">
<?php <?php
$users = session()->get('user'); $users = session()->get('user');
if($users && $users['group_name'] == 'COMMERCIALE' && $is_editable): if($users && $users['group_name'] == 'COMMERCIALE'):
?> ?>
<input type="text" <input type="text" class="form-control" id="discount" name="discount" placeholder="Discount" onkeyup="subAmount()" value="<?php echo $order_data['order']['discount'] ?>" autocomplete="off">
class="form-control" <?php else: ?>
id="discount" <input type="text" class="form-control" id="discount" name="discount" readonly value="<?php echo $order_data['order']['discount'] ?>" autocomplete="off">
name="discount" <?php endif; ?>
placeholder="Discount"
onkeyup="subAmount()"
value="<?php echo $order_data['order']['discount'] ?>"
autocomplete="off">
<?php else: ?>
<input type="text"
class="form-control"
id="discount"
name="discount"
readonly
value="<?php echo $order_data['order']['discount'] ?>"
autocomplete="off">
<?php endif; ?>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="net_amount" class="col-sm-5 control-label">Remise</label> <label for="net_amount" class="col-sm-5 control-label">Remise</label>
<div class="col-sm-7"> <div class="col-sm-7">
<input type="text" <input type="text" class="form-control" id="net_amount" name="net_amount" disabled value="<?php echo $order_data['order']['net_amount'] ?>" autocomplete="off">
class="form-control" <input type="hidden" class="form-control" id="net_amount_value" name="net_amount_value" value="<?php echo $order_data['order']['net_amount'] ?>" autocomplete="off">
id="net_amount"
name="net_amount"
disabled
value="<?php echo $order_data['order']['net_amount'] ?>"
autocomplete="off">
<input type="hidden"
class="form-control"
id="net_amount_value"
name="net_amount_value"
value="<?php echo $order_data['order']['net_amount'] ?>"
autocomplete="off">
</div> </div>
</div> </div>
@ -339,10 +220,7 @@
<div class="form-group"> <div class="form-group">
<label for="paid_status" class="col-sm-5 control-label">Tranche de paiement</label> <label for="paid_status" class="col-sm-5 control-label">Tranche de paiement</label>
<div class="col-sm-7"> <div class="col-sm-7">
<select class="form-control" <select class="form-control" id="payment_mode" name="payment_mode">
id="payment_mode"
name="payment_mode"
<?php echo !$is_editable ? 'disabled' : ''; ?>>
<option value="1" selected>une tranche</option> <option value="1" selected>une tranche</option>
<option value="2">deux tranches</option> <option value="2">deux tranches</option>
</select> </select>
@ -362,57 +240,44 @@
<div class="form-group" id="paid_status_1" style="display: none"> <div class="form-group" id="paid_status_1" style="display: none">
<label for="paid_status_1" class="col-sm-5 control-label">Tranche 1</label> <label for="paid_status_1" class="col-sm-5 control-label">Tranche 1</label>
<div class="col-sm-3"> <div class="col-sm-3">
<select class="form-control" <select class="form-control" id="payment_mode_1" name="order_payment_mode_1">
id="payment_mode_1"
name="order_payment_mode_1"
<?php echo !$is_editable ? 'disabled' : ''; ?>>
<option value="MVOLA">MVOLA</option> <option value="MVOLA">MVOLA</option>
<option value="Virement Bancaire">Virement Bancaire</option> <option value="Virement Bancaire">Virement Bancaire</option>
<option value="En espèce">En espèce</option> <option value="En espèce">En espèce</option>
</select> </select>
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<input type="number" <input type="number" class="form-control" id="payment_amount_1"
class="form-control" name="tranche_1" placeholder="Montant" onkeyup="calculerTranche2()">
id="payment_amount_1"
name="tranche_1"
placeholder="Montant"
onkeyup="calculerTranche2()"
<?php echo !$is_editable ? 'disabled readonly' : ''; ?>>
</div> </div>
</div> </div>
<div class="form-group" id="paid_status_2" style="display: none"> <div class="form-group" id="paid_status_2" style="display: none">
<label for="paid_status_2" class="col-sm-5 control-label">Tranche 2 (Reste)</label> <label for="paid_status_2" class="col-sm-5 control-label">Tranche 2 (Reste)</label>
<div class="col-sm-3"> <div class="col-sm-3">
<select class="form-control" <select class="form-control" id="payment_mode_2" name="order_payment_mode_2">
id="payment_mode_2"
name="order_payment_mode_2"
<?php echo !$is_editable ? 'disabled' : ''; ?>>
<option value="MVOLA">MVOLA</option> <option value="MVOLA">MVOLA</option>
<option value="Virement Bancaire">Virement Bancaire</option> <option value="Virement Bancaire">Virement Bancaire</option>
<option value="En espèce">En espèce</option> <option value="En espèce">En espèce</option>
</select> </select>
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<input type="number" <input type="number" class="form-control" id="payment_amount_2"
class="form-control" name="tranche_2" placeholder="Montant" readonly>
id="payment_amount_2"
name="tranche_2"
placeholder="Montant"
readonly>
</div> </div>
</div> </div>
</div> </div>
<?php endif; ?>
<?php
$users = session()->get('user');
if ($users && $users['group_name'] !== 'COMMERCIALE'):
?>
<div class="form-group"> <div class="form-group">
<label for="paid_status" class="col-sm-5 control-label">Statut payant</label> <label for="paid_status" class="col-sm-5 control-label">Statut payant</label>
<div class="col-sm-7"> <div class="col-sm-7">
<select type="text" <select type="text" class="form-control" id="paid_status" name="paid_status">
class="form-control"
id="paid_status"
name="paid_status"
<?php echo !$is_editable ? 'disabled' : ''; ?>>
<option value="1">Validé</option> <option value="1">Validé</option>
<option value="2">Refusé</option> <option value="2">Refusé</option>
</select> </select>
@ -422,64 +287,24 @@
</div> </div>
</div> </div>
<!-- /.box-body -->
<div class="box-footer"> <div class="box-footer">
<input type="hidden" name="service_charge_rate" value="<?php echo $company_data['service_charge_value'] ?>" autocomplete="off"> <input type="hidden" name="service_charge_rate" value="<?php echo $company_data['service_charge_value'] ?>" autocomplete="off">
<input type="hidden" name="vat_charge_rate" value="<?php echo $company_data['vat_charge_value'] ?>" autocomplete="off"> <input type="hidden" name="vat_charge_rate" value="<?php echo $company_data['vat_charge_value'] ?>" autocomplete="off">
<a target="__blank" id="Imprimente" href="<?php echo base_url() . 'orders/printDiv/' . $order_data['order']['id'] ?>" class="btn btn-default">Imprimer</a> <a target="__blank" id="Imprimente" href="<?php echo base_url() . 'orders/printDiv/' . $order_data['order']['id'] ?>" class="btn btn-default">Imprimer</a>
<button type="submit" class="btn btn-primary">Enregistrer</button>
<?php if ($is_editable): ?>
<button type="submit" class="btn btn-primary">Enregistrer</button>
<?php endif; ?>
<a href="<?php echo base_url('orders/') ?>" class="btn btn-warning">Retour</a> <a href="<?php echo base_url('orders/') ?>" class="btn btn-warning">Retour</a>
</div> </div>
</form> </form>
<!-- /.box-body -->
</div> </div>
<!-- /.box -->
</div> </div>
<!-- col-md-12 -->
</div> </div>
<!-- /.row -->
</section> </section>
<!-- /.content -->
</div> </div>
<!-- /.content-wrapper -->
<style>
/* ✅ Animation pour l'alerte */
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* ✅ Style pour l'input en erreur */
.input-error {
border: 2px solid #dc3545 !important;
box-shadow: 0 0 8px rgba(220, 53, 69, 0.5) !important;
animation: pulse 0.5s ease-in-out;
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 8px rgba(220, 53, 69, 0.5); }
50% { box-shadow: 0 0 15px rgba(220, 53, 69, 0.8); }
}
</style>
<script type="text/javascript"> <script type="text/javascript">
var base_url = "<?php echo base_url(); ?>"; var base_url = "<?php echo base_url(); ?>";
var idData = "<?php echo $order_data['order']['id']; ?>"; var idData = "<?php echo $order_data['order']['id']; ?>";
var is_editable = <?php echo $is_editable ? 'true' : 'false'; ?>;
let Imprimente = document.getElementById('Imprimente'); let Imprimente = document.getElementById('Imprimente');
let typesCommande = document.getElementById('typesCommande'); let typesCommande = document.getElementById('typesCommande');
@ -496,77 +321,12 @@
} }
}); });
// ============================================
// 🔹 FONCTION D'ALERTE VISUELLE
// ============================================
function showPriceAlert(message) {
const alertBox = $('#price_alert');
const discountInput = $('#discount');
$('#price_alert_message').text(message);
alertBox.slideDown(300);
discountInput.addClass('input-error');
setTimeout(function() {
alertBox.slideUp(300);
discountInput.removeClass('input-error');
}, 3500);
}
function hidePriceAlert() {
$('#price_alert').slideUp(300);
$('#discount').removeClass('input-error');
}
// ============================================
// 🔹 VALIDATION DU PRIX DEMANDÉ
// ============================================
function validateDiscount() {
if (!is_editable) return true; // ✅ Pas de validation si non éditable
var discount = parseFloat($('#discount').val());
var grossAmount = parseFloat($('#gross_amount_value').val()) || 0;
if (discount < 0) {
showPriceAlert("Le prix demandé ne peut pas être négatif !");
$('#discount').val('');
return false;
}
if (discount > grossAmount) {
showPriceAlert("Le prix demandé ne peut pas dépasser le prix affiché (" + grossAmount.toFixed(2) + ") !");
$('#discount').val(grossAmount.toFixed(2));
subAmount();
return false;
}
hidePriceAlert();
return true;
}
$(document).ready(function() { $(document).ready(function() {
$(".select_group").select2(); $(".select_group").select2();
$("#mainOrdersNav").addClass('active'); $("#mainOrdersNav").addClass('active');
$("#manageOrdersNav").addClass('active'); $("#manageOrdersNav").addClass('active');
// ✅ Désactiver toutes les interactions si non éditable
if (!is_editable) {
$('input, select, textarea').prop('disabled', true);
$('#add_row').hide();
$('.btn-default[onclick^="removeRow"]').hide();
}
// ✅ Validation en temps réel du prix demandé
if (is_editable) {
$('#discount').on('keyup change', function() {
validateDiscount();
});
}
// ============================================
// 🔹 GESTION DES TRANCHES DE PAIEMENT
// ============================================
var paymentTranche = 1; var paymentTranche = 1;
var netAmount = parseFloat($('#net_amount_value').val()) || 0; var netAmount = parseFloat($('#net_amount_value').val()) || 0;
$('#payment_amount_1').val(netAmount); $('#payment_amount_1').val(netAmount);
@ -587,75 +347,67 @@
} }
$("#payment_mode").on("change", function() { $("#payment_mode").on("change", function() {
if (is_editable) { addPaymentTranche($(this).val());
addPaymentTranche($(this).val()); updateMontantTranches();
updateMontantTranches();
}
}); });
$('#payment_amount_1').on("input", function() { $('#payment_amount_1').on("input", function() {
if (is_editable) { var amount1 = parseFloat($(this).val()) || 0;
var amount1 = parseFloat($(this).val()) || 0; var amount2 = netAmount - amount1;
var amount2 = netAmount - amount1; $('#payment_amount_2').val(amount2);
$('#payment_amount_2').val(amount2);
}
}); });
addPaymentTranche(paymentTranche); addPaymentTranche(paymentTranche);
// ============================================ $("#add_row").unbind('click').bind('click', function() {
// 🔹 TABLEAU DE PRODUITS var table = $("#product_info_table");
// ============================================ var count_table_tbody_tr = $("#product_info_table tbody tr").length;
if (is_editable) { var row_id = count_table_tbody_tr + 1;
$("#add_row").unbind('click').bind('click', function() {
var table = $("#product_info_table");
var count_table_tbody_tr = $("#product_info_table tbody tr").length;
var row_id = count_table_tbody_tr + 1;
$.ajax({ $.ajax({
url: base_url + '/orders/getTableProductRow/', url: base_url + '/orders/getTableProductRow/',
type: 'post', type: 'post',
dataType: 'json', dataType: 'json',
success: function(response) { success: function(response) {
var html = '<tr id="row_' + row_id + '">' + var html = '<tr id="row_' + row_id + '">' +
'<td>' + '<td>' +
'<select class="form-control select_group product" data-row-id="' + row_id + '" id="product_' + row_id + '" name="product[]" style="width:100%;" onchange="getProductData(' + row_id + ')">' + '<select class="form-control select_group product" data-row-id="' + row_id + '" id="product_' + row_id + '" name="product[]" style="width:100%;" onchange="getProductData(' + row_id + ')">' +
'<option value=""></option>'; '<option value=""></option>';
$.each(response, function(index, value) { $.each(response, function(index, value) {
html += '<option value="' + value.id + '">' + value.name + '</option>'; var displayText = value.sku + ' | ' + value.name;
if (value.numero_de_moteur) {
displayText += ' | ' + value.numero_de_moteur;
}
// ✅ Ne plus afficher la puissance
html += '<option value="' + value.id + '">' + displayText + '</option>';
}); });
html += '</select>' + html += '</select>' +
'</td>' + '</td>' +
'<td><input type="number" name="qty[]" id="qty_' + row_id + '" class="form-control" onkeyup="getTotal(' + row_id + ')"></td>' + // ✅ Colonne puissance visible et modifiable
'<td><input type="text" name="rate[]" id="rate_' + row_id + '" class="form-control" disabled><input type="hidden" name="rate_value[]" id="rate_value_' + row_id + '" class="form-control"></td>' + '<td><input type="text" name="puissance[]" id="puissance_' + row_id + '" class="form-control" placeholder="Puissance" autocomplete="off" value="1"></td>' +
'<td><input type="text" name="amount[]" id="amount_' + row_id + '" class="form-control" disabled><input type="hidden" name="amount_value[]" id="amount_value_' + row_id + '" class="form-control"></td>' + '<td><input type="text" name="rate[]" id="rate_' + row_id + '" class="form-control numeric-input" disabled min="0"><input type="hidden" name="rate_value[]" id="rate_value_' + row_id + '" class="form-control"><input type="hidden" id="min_price_' + row_id + '" name="min_price[]" value=""></td>' +
'<td><button type="button" class="btn btn-default" onclick="removeRow(\'' + row_id + '\')"><i class="fa fa-close"></i></button></td>' + '<td><input type="text" name="amount[]" id="amount_' + row_id + '" class="form-control numeric-input" disabled min="0"><input type="hidden" name="amount_value[]" id="amount_value_' + row_id + '" class="form-control"></td>' +
'</tr>'; '<td><button type="button" class="btn btn-default" onclick="removeRow(\'' + row_id + '\')"><i class="fa fa-close"></i></button></td>' +
'</tr>';
if (count_table_tbody_tr >= 1) { if (count_table_tbody_tr >= 1) {
$("#product_info_table tbody tr:last").after(html); $("#product_info_table tbody tr:last").after(html);
} else { } else {
$("#product_info_table tbody").html(html); $("#product_info_table tbody").html(html);
} }
$(".product").select2(); $(".product").select2();
} }
}); });
return false; return false;
}); });
}
}); // /document.ready
// ============================================
// 🔹 CALCUL DU TOTAL
// ============================================
function getTotal(row = null) { function getTotal(row = null) {
if (!is_editable) return; // ✅ Bloquer si non éditable
if (row) { if (row) {
var total = Number($("#rate_value_" + row).val()) * Number($("#qty_" + row).val()); var total = Number($("#rate_value_" + row).val());
total = total.toFixed(2); total = total.toFixed(2);
$("#amount_" + row).val(total); $("#amount_" + row).val(total);
$("#amount_value_" + row).val(total); $("#amount_value_" + row).val(total);
@ -665,44 +417,56 @@
} }
} }
// 🔹 OBTENIR LES DONNÉES PRODUIT
function getProductData(row_id) { function getProductData(row_id) {
if (!is_editable) return; // ✅ Bloquer si non éditable
var product_id = $("#product_" + row_id).val(); var product_id = $("#product_" + row_id).val();
if (product_id == "") { if (product_id == "") {
$("#rate_" + row_id).val(""); $("#rate_" + row_id).val("");
$("#rate_value_" + row_id).val(""); $("#rate_value_" + row_id).val("");
$("#qty_" + row_id).val(""); $("#min_price_" + row_id).val("");
$("#amount_" + row_id).val(""); $("#puissance_" + row_id).val("1"); // ✅ Réinitialiser à 1
$("#amount_value_" + row_id).val(""); $("#amount_" + row_id).val("");
$("#amount_value_" + row_id).val("");
} else { } else {
$.ajax({ $.ajax({
url: base_url + 'orders/getProductValueById', url: base_url + 'orders/getProductValueById',
type: 'post', type: 'post',
data: { product_id: product_id }, data: { product_id: product_id },
dataType: 'json', dataType: 'json',
success: function(response) { success: function(response) {
$("#rate_" + row_id).val(response.price); console.log('✅ Response:', response); // Debug
$("#rate_value_" + row_id).val(response.price);
$("#qty_" + row_id).val(1); var prixVente = parseFloat(response.prix_vente) || 0;
$("#qty_value_" + row_id).val(1); var prixMinimal = parseFloat(response.prix_minimal) || 0;
var total = Number(response.price) * 1;
total = total.toFixed(2); if (prixVente < 0) prixVente = 0;
$("#amount_" + row_id).val(total); if (prixMinimal < 0) prixMinimal = 0;
$("#amount_value_" + row_id).val(total);
subAmount(); $("#rate_" + row_id).val(prixVente);
} $("#rate_value_" + row_id).val(prixVente);
}); $("#min_price_" + row_id).val(prixMinimal);
// ✅ CORRECTION : Remplir la puissance
var puissanceValue = response.puissance || '1';
console.log('✅ Puissance extraite:', puissanceValue); // Debug
$("#puissance_" + row_id).val(puissanceValue);
// ✅ Calculer le montant (prix * puissance)
var total = prixVente * 1; // Pour l'instant on garde qty=1
total = total.toFixed(2);
$("#amount_" + row_id).val(total);
$("#amount_value_" + row_id).val(total);
subAmount();
},
error: function(xhr, status, error) {
console.error('❌ Erreur AJAX:', error);
}
});
} }
} }
// ============================================
// 🔹 CALCUL DU MONTANT TOTAL (AVEC TVA, REMISE, ETC.)
// ============================================
function subAmount() { function subAmount() {
if (!is_editable) return; // ✅ Bloquer si non éditable
var service_charge = <?php echo ($company_data['service_charge_value'] > 0) ? $company_data['service_charge_value'] : 0; ?>; var service_charge = <?php echo ($company_data['service_charge_value'] > 0) ? $company_data['service_charge_value'] : 0; ?>;
var vat_charge = <?php echo ($company_data['vat_charge_value'] > 0) ? $company_data['vat_charge_value'] : 0; ?>; var vat_charge = <?php echo ($company_data['vat_charge_value'] > 0) ? $company_data['vat_charge_value'] : 0; ?>;
@ -734,12 +498,10 @@
var discount = $("#discount").val(); var discount = $("#discount").val();
if (discount) { if (discount) {
if (validateDiscount()) { var grandTotal = Number(totalAmount) - Number(discount);
var grandTotal = Number(totalAmount) - Number(discount); grandTotal = grandTotal.toFixed(2);
grandTotal = grandTotal.toFixed(2); $("#net_amount").val(grandTotal);
$("#net_amount").val(grandTotal); $("#net_amount_value").val(grandTotal);
$("#net_amount_value").val(grandTotal);
}
} else { } else {
$("#net_amount").val(totalAmount); $("#net_amount").val(totalAmount);
$("#net_amount_value").val(totalAmount); $("#net_amount_value").val(totalAmount);
@ -756,12 +518,7 @@
updateMontantTranches(); updateMontantTranches();
} }
// ============================================
// 🔹 AUTRES FONCTIONS
// ============================================
function paidAmount() { function paidAmount() {
if (!is_editable) return;
var grandTotal = $("#net_amount_value").val(); var grandTotal = $("#net_amount_value").val();
if (grandTotal) { if (grandTotal) {
var dueAmount = Number($("#net_amount_value").val()) - Number($("#paid_amount").val()); var dueAmount = Number($("#net_amount_value").val()) - Number($("#paid_amount").val());
@ -772,15 +529,10 @@
} }
function removeRow(tr_id) { function removeRow(tr_id) {
if (!is_editable) return; // ✅ Bloquer si non éditable
$("#product_info_table tbody tr#row_" + tr_id).remove(); $("#product_info_table tbody tr#row_" + tr_id).remove();
subAmount(); subAmount();
} }
// ============================================
// 🔹 GESTION MONTANT DE TRANCHES
// ============================================
function getMontantPourTranches() { function getMontantPourTranches() {
var discount = parseFloat($("#discount").val()) || 0; var discount = parseFloat($("#discount").val()) || 0;
var grossAmount = parseFloat($("#gross_amount_value").val()) || 0; var grossAmount = parseFloat($("#gross_amount_value").val()) || 0;
@ -788,8 +540,6 @@
} }
function updateMontantTranches() { function updateMontantTranches() {
if (!is_editable) return;
var montant = getMontantPourTranches(); var montant = getMontantPourTranches();
var discount = parseFloat($("#discount").val()) || 0; var discount = parseFloat($("#discount").val()) || 0;
@ -808,8 +558,6 @@
} }
function calculerTranche2() { function calculerTranche2() {
if (!is_editable) return;
var montantTotal = getMontantPourTranches(); var montantTotal = getMontantPourTranches();
var tranche1 = parseFloat($("#payment_amount_1").val()) || 0; var tranche1 = parseFloat($("#payment_amount_1").val()) || 0;
var tranche2 = montantTotal - tranche1; var tranche2 = montantTotal - tranche1;
@ -817,16 +565,12 @@
$("#payment_amount_2").val(tranche2.toFixed(2)); $("#payment_amount_2").val(tranche2.toFixed(2));
} }
if (is_editable) { $("#discount").on('keyup', function() {
$("#discount").on('keyup', function() { updateMontantTranches();
updateMontantTranches(); });
});
}
const net_amount_value = document.getElementById('net_amount_value'); const net_amount_value = document.getElementById('net_amount_value');
const net_amount = document.getElementById('net_amount'); const net_amount = document.getElementById('net_amount');
const payment_amount_1 = document.getElementById('payment_amount_1'); const payment_amount_1 = document.getElementById('payment_amount_1');
if (payment_amount_1 && net_amount) { payment_amount_1.value = net_amount.value;
payment_amount_1.value = net_amount.value;
}
</script> </script>

4
app/Views/orders/index.php

@ -56,7 +56,7 @@
<th>Nom du client</th> <th>Nom du client</th>
<th>Téléphone du client</th> <th>Téléphone du client</th>
<th>Date et Heure</th> <th>Date et Heure</th>
<th>Remise</th> <th>Prix demandé</th>
<th>Prix de vente</th> <th>Prix de vente</th>
<th>Validation</th> <th>Validation</th>
@ -77,7 +77,7 @@
<th>Nom du produit</th> <th>Nom du produit</th>
<th>Commerciale</th> <th>Commerciale</th>
<th>Date et Heure</th> <th>Date et Heure</th>
<th>Remise</th> <th>Prix demandé</th>
<th>Prix de vente</th> <th>Prix de vente</th>
<th>Validation</th> <th>Validation</th>
<?php if ( <?php if (

Loading…
Cancel
Save