Sarobidy22 1 month ago
parent
commit
6f2b1d3661
  1. 40
      app/Controllers/OrderController.php
  2. 10
      app/Models/Orders.php
  3. 29
      app/Views/orders/createbyid.php
  4. 54
      app/Views/orders/edit.php

40
app/Controllers/OrderController.php

@ -343,12 +343,18 @@ class OrderController extends AdminController
return redirect()->back()->withInput()->with('errors', ['product' => 'Chaque produit sélectionné doit être unique.']); return redirect()->back()->withInput()->with('errors', ['product' => 'Chaque produit sélectionné doit être unique.']);
} }
// ✅ AJOUT DES RÈGLES DE VALIDATION
$validation->setRules([ $validation->setRules([
'product[]' => 'required' 'product[]' => 'required',
'customer_type' => 'required',
'source' => 'required'
]); ]);
// ✅ AJOUT DES DONNÉES DE VALIDATION
$validationData = [ $validationData = [
'product[]' => $this->request->getPost('product[]') 'product[]' => $this->request->getPost('product[]'),
'customer_type' => $this->request->getPost('customer_type'),
'source' => $this->request->getPost('source')
]; ];
$Orders = new Orders(); $Orders = new Orders();
@ -361,7 +367,6 @@ class OrderController extends AdminController
$users = $session->get('user'); $users = $session->get('user');
$user_id = $users['id']; $user_id = $users['id'];
// ✅ UTILISER LA NOUVELLE MÉTHODE
$bill_no = $this->generateBillNo($users['store_id']); $bill_no = $this->generateBillNo($users['store_id']);
// Récupération des produits // Récupération des produits
@ -372,7 +377,7 @@ class OrderController extends AdminController
$discount = (float)$this->request->getPost('discount') ?? 0; $discount = (float)$this->request->getPost('discount') ?? 0;
$gross_amount = $this->calculGross($amounts); $gross_amount = $this->calculGross($amounts);
// Vérification prix minimal SI rabais existe // Vérification prix minimal SI rabais existe
if ($discount > 0) { if ($discount > 0) {
$FourchettePrix = new \App\Models\FourchettePrix(); $FourchettePrix = new \App\Models\FourchettePrix();
@ -399,7 +404,7 @@ class OrderController extends AdminController
} }
} }
// Calculer le montant à payer et net_amount // Calculer le montant à payer et net_amount
$montant_a_payer = ($discount > 0) ? $discount : $gross_amount; $montant_a_payer = ($discount > 0) ? $discount : $gross_amount;
$tranche_1 = (float)$this->request->getPost('tranche_1') ?? 0; $tranche_1 = (float)$this->request->getPost('tranche_1') ?? 0;
@ -411,13 +416,15 @@ class OrderController extends AdminController
$net_amount = $montant_a_payer; $net_amount = $montant_a_payer;
} }
// ✅ Création de la commande // ✅ AJOUT DES NOUVEAUX CHAMPS ICI
$data = [ $data = [
'bill_no' => $bill_no, 'bill_no' => $bill_no,
'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'),
'customer_cin' => $this->request->getPost('customer_cin'), 'customer_cin' => $this->request->getPost('customer_cin'),
'customer_type' => $this->request->getPost('customer_type'), // ✅ NOUVEAU
'source' => $this->request->getPost('source'), // ✅ NOUVEAU
'date_time' => date('Y-m-d H:i:s'), 'date_time' => date('Y-m-d H:i:s'),
'service_charge_rate' => 0, 'service_charge_rate' => 0,
'vat_charge_rate' => 0, 'vat_charge_rate' => 0,
@ -689,7 +696,9 @@ public function update(int $id)
$Orders = new Orders(); $Orders = new Orders();
$current_order = $Orders->getOrdersData($id); $current_order = $Orders->getOrdersData($id);
if (!$current_order) { // ✅ AJOUT : Vérification plus détaillée
if (!$current_order || !isset($current_order['id'])) {
log_message('error', 'Commande introuvable pour ID: ' . $id);
session()->setFlashData('errors', 'Commande introuvable.'); session()->setFlashData('errors', 'Commande introuvable.');
return redirect()->to('orders/'); return redirect()->to('orders/');
} }
@ -731,17 +740,14 @@ public function update(int $id)
$paid_status = $this->request->getPost('paid_status'); $paid_status = $this->request->getPost('paid_status');
} }
// ✅ AJOUT : TRACER LA VALIDATION PAR LE CAISSIER $validated_by = $current_order['validated_by'] ?? null;
$validated_by = $current_order['validated_by'] ?? null; // Garder l'ancienne valeur si existe
$validated_at = $current_order['validated_at'] ?? null; $validated_at = $current_order['validated_at'] ?? null;
// Si le statut passe à "Validé" (1) et que l'utilisateur est un caissier
if ($old_paid_status != 1 && $paid_status == 1 && $role === 'Caissière') { if ($old_paid_status != 1 && $paid_status == 1 && $role === 'Caissière') {
$validated_by = $user['id']; $validated_by = $user['id'];
$validated_at = date('Y-m-d H:i:s'); $validated_at = date('Y-m-d H:i:s');
} }
// Si le statut repasse à "En attente" ou "Refusé", effacer la validation
if (in_array($paid_status, [0, 2])) { if (in_array($paid_status, [0, 2])) {
$validated_by = null; $validated_by = null;
$validated_at = null; $validated_at = null;
@ -758,6 +764,8 @@ public function update(int $id)
'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'),
'customer_cin' => $this->request->getPost('customer_cin'), 'customer_cin' => $this->request->getPost('customer_cin'),
'customer_type' => $this->request->getPost('customer_type'),
'source' => $this->request->getPost('source'),
'gross_amount' => $this->request->getPost('gross_amount_value'), 'gross_amount' => $this->request->getPost('gross_amount_value'),
'service_charge_rate' => $this->request->getPost('service_charge_rate'), 'service_charge_rate' => $this->request->getPost('service_charge_rate'),
'service_charge' => max(0, (float)$this->request->getPost('service_charge_value')), 'service_charge' => max(0, (float)$this->request->getPost('service_charge_value')),
@ -775,7 +783,6 @@ public function update(int $id)
'tranche_2' => $role !== 'COMMERCIALE' ? $this->request->getPost('tranche_2') : null, 'tranche_2' => $role !== 'COMMERCIALE' ? $this->request->getPost('tranche_2') : null,
'order_payment_mode' => $role !== 'COMMERCIALE' ? $this->request->getPost('order_payment_mode_1') : null, 'order_payment_mode' => $role !== 'COMMERCIALE' ? $this->request->getPost('order_payment_mode_1') : null,
'order_payment_mode_1' => $role !== 'COMMERCIALE' ? $this->request->getPost('order_payment_mode_2') : null, 'order_payment_mode_1' => $role !== 'COMMERCIALE' ? $this->request->getPost('order_payment_mode_2') : null,
// ✅ AJOUT DES CHAMPS DE TRACABILITÉ
'validated_by' => $validated_by, 'validated_by' => $validated_by,
'validated_at' => $validated_at 'validated_at' => $validated_at
]; ];
@ -797,7 +804,6 @@ public function update(int $id)
'orders' 'orders'
); );
// ✅ AJOUT : Notification pour la Direction quand un caissier valide
if ($role === 'Caissière') { if ($role === 'Caissière') {
$Notification->createNotification( $Notification->createNotification(
"Commande validée par la caisse: {$bill_no}", "Commande validée par la caisse: {$bill_no}",
@ -854,6 +860,7 @@ public function update(int $id)
} }
} }
// ✅ Affichage du formulaire
$company = $Company->getCompanyData(1); $company = $Company->getCompanyData(1);
$data['company_data'] = $company; $data['company_data'] = $company;
$data['is_vat_enabled'] = ($company['vat_charge_value'] > 0); $data['is_vat_enabled'] = ($company['vat_charge_value'] > 0);
@ -861,6 +868,13 @@ public function update(int $id)
$orders_data = $Orders->getOrdersData($id); $orders_data = $Orders->getOrdersData($id);
// ✅ VÉRIFICATION SUPPLÉMENTAIRE
if (!$orders_data || !isset($orders_data['id'])) {
log_message('error', 'Données de commande vides pour ID: ' . $id);
session()->setFlashData('errors', 'Impossible de charger les données de la commande.');
return redirect()->to('orders/');
}
$data['is_editable'] = !in_array($orders_data['paid_status'], [1, 3]); $data['is_editable'] = !in_array($orders_data['paid_status'], [1, 3]);
$orders_data['montant_tranches'] = (!empty($orders_data['discount']) && $orders_data['discount'] > 0) $orders_data['montant_tranches'] = (!empty($orders_data['discount']) && $orders_data['discount'] > 0)

10
app/Models/Orders.php

@ -20,6 +20,8 @@ class Orders extends Model
'customer_address', 'customer_address',
'customer_phone', 'customer_phone',
'customer_cin', 'customer_cin',
'customer_type',
'source',
'date_time', 'date_time',
'gross_amount', 'gross_amount',
'service_charge_rate', 'service_charge_rate',
@ -84,17 +86,17 @@ class Orders extends Model
$session = session(); $session = session();
$user = $session->get('user'); $user = $session->get('user');
// Si on demande UNE commande spécifique (pas de GROUP_CONCAT) // ✅ CORRECTION : Si on demande UNE commande spécifique
if ($id !== null) { if ($id !== null) {
return $this->db->table('orders') return $this->db->table('orders')
->select([ ->select([
'orders.*', 'orders.*', // ✅ Ceci inclut déjà customer_type et source
"CONCAT(users.firstname, ' ', users.lastname) AS user_name" "CONCAT(users.firstname, ' ', users.lastname) AS user_name"
]) ])
->join('users', 'orders.user_id = users.id', 'left') ->join('users', 'orders.user_id = users.id', 'left')
->where('orders.id', $id) ->where('orders.id', $id)
->get() ->get()
->getRowArray(); ->getRowArray(); // ✅ Retourne bien un tableau associatif
} }
// Pour la LISTE des commandes (avec GROUP_CONCAT) // Pour la LISTE des commandes (avec GROUP_CONCAT)
@ -107,6 +109,8 @@ class Orders extends Model
'orders.customer_phone', 'orders.customer_phone',
'orders.customer_cin', 'orders.customer_cin',
'orders.customer_address', 'orders.customer_address',
'orders.customer_type', // ✅ DÉJÀ PRÉSENT
'orders.source', // ✅ DÉJÀ PRÉSENT
'orders.discount', 'orders.discount',
'orders.date_time', 'orders.date_time',
'orders.gross_amount', 'orders.gross_amount',

29
app/Views/orders/createbyid.php

@ -72,6 +72,35 @@
<div class="col-md-4 col-xs-12 pull pull-left"> <div class="col-md-4 col-xs-12 pull pull-left">
<!-- ✅ NOUVEAU CHAMP : Type de client -->
<div class="form-group">
<label for="customer_type" class="col-sm-5 control-label"
style="text-align:left;">Type de client</label>
<div class="col-sm-7">
<select class="form-control" id="customer_type" name="customer_type" required>
<option value="">-- Sélectionner --</option>
<option value="particulier" <?= old('customer_type') == 'particulier' ? 'selected' : '' ?>>Particulier</option>
<option value="revendeur" <?= old('customer_type') == 'revendeur' ? 'selected' : '' ?>>Revendeur</option>
</select>
</div>
</div>
<!-- ✅ NOUVEAU CHAMP : Source -->
<div class="form-group">
<label for="source" class="col-sm-5 control-label"
style="text-align:left;">Source</label>
<div class="col-sm-7">
<select class="form-control" id="source" name="source" required>
<option value="">-- Sélectionner --</option>
<option value="facebook_perso" <?= old('source') == 'facebook_perso' ? 'selected' : '' ?>>Facebook perso</option>
<option value="page_motorbike" <?= old('source') == 'page_motorbike' ? 'selected' : '' ?>>Page motorbike</option>
<option value="bouche_a_oreille" <?= old('source') == 'bouche_a_oreille' ? 'selected' : '' ?>>Bouche à oreille</option>
<option value="commercial_interne" <?= old('source') == 'commercial_interne' ? 'selected' : '' ?>>Commercial interne</option>
<option value="autre" <?= old('source') == 'autre' ? 'selected' : '' ?>>Autre</option>
</select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="customer_name" class="col-sm-5 control-label" <label for="customer_name" class="col-sm-5 control-label"
style="text-align:left;">Nom du client</label> style="text-align:left;">Nom du client</label>

54
app/Views/orders/edit.php

@ -85,25 +85,53 @@
</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="customer_address" 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" class="form-control" id="customer_address" name="customer_address" placeholder="Enter Customer Address" value="<?php echo $order_data['order']['customer_address'] ?>" autocomplete="off"> <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">
</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="customer_phone" 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" class="form-control" id="customer_phone" name="customer_phone" placeholder="Enter Customer Phone" value="<?php echo $order_data['order']['customer_phone'] ?>" autocomplete="off"> <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">
</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="customer_cin" 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" class="form-control" id="customer_cin" name="customer_cin" placeholder="Enter Customer CIN" value="<?php echo $order_data['order']['customer_cin'] ?>" autocomplete="off"> <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">
</div> </div>
</div> </div>
<!-- ✅ NOUVEAU CHAMP : Type de client -->
<div class="form-group">
<label for="customer_type" class="col-sm-5 control-label" style="text-align:left;">Type de client <span class="text-danger">*</span></label>
<div class="col-sm-7">
<select class="form-control" id="customer_type" name="customer_type" required>
<option value="">-- Sélectionner --</option>
<option value="particulier" <?php echo (isset($order_data['order']['customer_type']) && strtolower($order_data['order']['customer_type']) == 'particulier') ? 'selected' : ''; ?>>Particulier</option>
<option value="revendeur" <?php echo (isset($order_data['order']['customer_type']) && strtolower($order_data['order']['customer_type']) == 'revendeur') ? 'selected' : ''; ?>>Revendeur</option>
</select>
</div>
</div>
<!-- ✅ NOUVEAU CHAMP : Source -->
<div class="form-group">
<label for="source" class="col-sm-5 control-label" style="text-align:left;">Source <span class="text-danger">*</span></label>
<div class="col-sm-7">
<select class="form-control" id="source" name="source" required>
<option value="">-- Sélectionner --</option>
<option value="facebook_perso" <?php echo (isset($order_data['order']['source']) && $order_data['order']['source'] == 'facebook_perso') ? 'selected' : ''; ?>>Facebook perso</option>
<option value="page_motorbike" <?php echo (isset($order_data['order']['source']) && $order_data['order']['source'] == 'page_motorbike') ? 'selected' : ''; ?>>Page motorbike</option>
<option value="bouche_a_oreille" <?php echo (isset($order_data['order']['source']) && $order_data['order']['source'] == 'bouche_a_oreille') ? 'selected' : ''; ?>>Bouche à oreille</option>
<option value="commercial_interne" <?php echo (isset($order_data['order']['source']) && $order_data['order']['source'] == 'commercial_interne') ? 'selected' : ''; ?>>Commercial interne</option>
<option value="autre" <?php echo (isset($order_data['order']['source']) && $order_data['order']['source'] == 'autre') ? 'selected' : ''; ?>>Autre</option>
</select>
</div>
</div>
</div> </div>
<br /> <br /> <br /> <br />
@ -142,7 +170,6 @@
</select> </select>
</td> </td>
<!-- ✅ COLONNE PUISSANCE VISIBLE -->
<td> <td>
<input type="number" name="puissance[]" id="puissance_<?php echo $x; ?>" <input type="number" name="puissance[]" id="puissance_<?php echo $x; ?>"
class="form-control" placeholder="Puissance" class="form-control" placeholder="Puissance"
@ -204,6 +231,7 @@
<?php endif; ?> <?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">
@ -327,10 +355,8 @@
$("#mainOrdersNav").addClass('active'); $("#mainOrdersNav").addClass('active');
$("#manageOrdersNav").addClass('active'); $("#manageOrdersNav").addClass('active');
// ✅ CORRECTION : Gestion des tranches de paiement
var paymentTranche = 1; var paymentTranche = 1;
// ✅ Fonction pour obtenir le montant à répartir (discount ou gross_amount)
function getMontantTotal() { function getMontantTotal() {
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;
@ -344,7 +370,7 @@
if (parseInt(paymentTranche) === 2) { if (parseInt(paymentTranche) === 2) {
$("#paid_status_1").show(); $("#paid_status_1").show();
$("#paid_status_2").show(); $("#paid_status_2").show();
$("#montant_reference").show(); // ✅ Afficher le montant de référence $("#montant_reference").show();
var amount1 = parseFloat($('#payment_amount_1').val()) || 0; var amount1 = parseFloat($('#payment_amount_1').val()) || 0;
var montantTotal = getMontantTotal(); var montantTotal = getMontantTotal();
@ -353,10 +379,9 @@
} else { } else {
$("#paid_status_1").show(); $("#paid_status_1").show();
$("#paid_status_2").hide(); $("#paid_status_2").hide();
$("#montant_reference").hide(); // ✅ Cacher le montant de référence $("#montant_reference").hide();
$('#payment_mode_2').val(''); $('#payment_mode_2').val('');
// ✅ Remplir tranche 1 avec le montant total
var montantTotal = getMontantTotal(); var montantTotal = getMontantTotal();
$('#payment_amount_1').val(montantTotal.toFixed(2)); $('#payment_amount_1').val(montantTotal.toFixed(2));
} }
@ -367,7 +392,6 @@
updateMontantTranches(); updateMontantTranches();
}); });
// ✅ CORRECTION : Recalculer tranche 2 quand tranche 1 change
$('#payment_amount_1').on("input", function() { $('#payment_amount_1').on("input", function() {
var amount1 = parseFloat($(this).val()) || 0; var amount1 = parseFloat($(this).val()) || 0;
var montantTotal = getMontantTotal(); var montantTotal = getMontantTotal();
@ -408,7 +432,7 @@
html += '</select>' + html += '</select>' +
'</td>' + '</td>' +
'<td><input type="text" name="puissance[]" id="puissance_' + row_id + '" class="form-control" placeholder="Puissance" autocomplete="off"></td>' + '<td><input type="number" name="puissance[]" id="puissance_' + row_id + '" class="form-control" placeholder="Puissance" autocomplete="off" min="1"></td>' +
'<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="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="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="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><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>' +
@ -519,7 +543,6 @@
$("#remaining_value").val(remaning.toFixed(2)); $("#remaining_value").val(remaning.toFixed(2));
} }
// ✅ CORRECTION : Mettre à jour les tranches après chaque calcul
updateMontantTranches(); updateMontantTranches();
} }
@ -538,14 +561,12 @@
subAmount(); subAmount();
} }
// ✅ CORRECTION : Fonction pour obtenir le montant pour les 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;
return discount > 0 ? discount : grossAmount; return discount > 0 ? discount : grossAmount;
} }
// ✅ CORRECTION : Mettre à jour l'affichage du montant de référence
function updateMontantTranches() { function updateMontantTranches() {
var montant = getMontantPourTranches(); var montant = getMontantPourTranches();
var discount = parseFloat($("#discount").val()) || 0; var discount = parseFloat($("#discount").val()) || 0;
@ -559,17 +580,14 @@
$("#montant_source_label").text("(Montant brut)"); $("#montant_source_label").text("(Montant brut)");
} }
// ✅ CORRECTION : Mettre à jour tranche 1 si en mode 1 tranche
var paymentMode = $("#payment_mode").val(); var paymentMode = $("#payment_mode").val();
if (parseInt(paymentMode) === 1) { if (parseInt(paymentMode) === 1) {
$("#payment_amount_1").val(montant.toFixed(2)); $("#payment_amount_1").val(montant.toFixed(2));
} else { } else {
// ✅ En mode 2 tranches, recalculer tranche 2
calculerTranche2(); calculerTranche2();
} }
} }
// ✅ CORRECTION : Calculer tranche 2 basé sur le montant total actuel
function calculerTranche2() { function calculerTranche2() {
var montantTotal = getMontantPourTranches(); var montantTotal = getMontantPourTranches();
var tranche1 = parseFloat($("#payment_amount_1").val()) || 0; var tranche1 = parseFloat($("#payment_amount_1").val()) || 0;
@ -578,12 +596,10 @@
$("#payment_amount_2").val(tranche2.toFixed(2)); $("#payment_amount_2").val(tranche2.toFixed(2));
} }
// ✅ CORRECTION : Écouter les changements de discount
$("#discount").on('keyup', function() { $("#discount").on('keyup', function() {
subAmount(); subAmount();
}); });
// ✅ Initialisation au chargement
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');

Loading…
Cancel
Save