You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1510 lines
61 KiB

<!-- CDN SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
/* Style pour les champs en lecture seule */
input[readonly], select[disabled], textarea[readonly] {
background-color: #e9ecef !important;
cursor: not-allowed !important;
color: #6c757d;
}
/* Style pour la légende */
.field-legend {
background-color: #f8f9fa;
border-left: 4px solid #007bff;
padding: 10px 15px;
margin-bottom: 20px;
border-radius: 4px;
}
.field-legend i {
margin-right: 5px;
}
.field-legend .legend-item {
display: inline-block;
margin-right: 20px;
margin-top: 5px;
}
/* Effet hover sur les champs éditables */
.form-control:not([readonly]):not([disabled]):hover {
border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.15);
transition: all 0.2s ease-in-out;
}
/* Icône d'édition */
.fa-edit {
font-size: 12px;
}
</style>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Gestion des
<small>Décaissement</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Accueil</a></li>
<li class="active">Décaissement</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-md-12 col-xs-12">
<div id="messages"></div>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<?php echo session()->getFlashdata('success'); ?>
</div>
<?php elseif (session()->getFlashdata('error')): ?>
<div class="alert alert-error alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<?php echo session()->getFlashdata('error'); ?>
</div>
<?php elseif (session()->getFlashdata('errors')): ?>
<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>
<?php echo session()->getFlashdata('errors'); ?>
</div>
<?php endif; ?>
<?php if (in_array('createSortieCaisse', $user_permission)): ?>
<button class="btn btn-primary" data-toggle="modal" data-target="#createModal">Décaissement</button>
<br><br>
<?php endif; ?>
<!-- FILTRES EN DESSUS DU TABLEAU -->
<div class="row mb-3">
<div class="col-md-2">
<label for="startDate" class="form-label">Date de début</label>
<input type="date" id="startDate" class="form-control">
</div>
<div class="col-md-2">
<label for="endDate" class="form-label">Date de fin</label>
<input type="date" id="endDate" class="form-control">
</div>
<div class="col-md-2">
<label for="pvente" class="form-label">Point de vente</label>
<select id="pvente" class="form-control">
<option value="TOUS">TOUS</option>
<?php foreach ($stores as $value): ?>
<option value="<?= $value['name']; ?>"><?= $value['name']; ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-2">
<label for="s_statut" class="form-label">Statut du décaissement</label>
<select id="s_statut" class="form-control">
<option value="TOUS">TOUS</option>
<option value="Valider">Valider</option>
<option value="En attente">En attente</option>
<option value="Refuser">Refuser</option>
</select>
</div>
<div class="col-md-1">
<br>
<button id="filteredB1" class="btn btn-primary w-100">Filtrer 🔍</button>
</div>
<div class="col-md-1">
<br>
<?php $session = session();
$users = $session->get('user');
$isAdmin = $users['group_name'] == "Direction" || $users['group_name'] == "Conseil";
$isCaissier = $users['group_name'] == "Caissière";
if($isAdmin): ?>
<button id="validate_filtered" class="btn btn-primary w-100">A valider</button>
<?php endif; ?>
</div>
</div>
<br>
<div class="box">
<div class="box-header">
<h3 class="box-title">Gérer les Décaissements</h3>
</div>
<div class="box-body">
<table id="manageTable" class="table table-bordered table-striped">
<thead>
<tr>
<?php
$session = session();
$users = $session->get('user');
if ($users['group_name'] === 'Caissière') {
?>
<th>#</th>
<th>Montant</th>
<th>Date</th>
<th>Caissier</th>
<th>Motif</th>
<th>Statut</th>
<th>Raison</th>
<?php if (in_array('updateSortieCaisse', $user_permission)) { ?>
<th>Action</th>
<?php } ?>
<?php
} elseif ($users['group_name'] === 'Direction' || $users['group_name'] === 'DAF') {
?>
<th>#</th>
<th>Montant</th>
<th>Date</th>
<th>Caissier</th>
<th>Motif</th>
<th>Source de fond</th>
<th>Initiateur de demande</th>
<th>Point de vente</th>
<th>Commentaire</th>
<th>Statut</th>
<?php if (in_array('updateSortieCaisse', $user_permission) || in_array('validateSortieCaisse', $user_permission)) { ?>
<th>Action</th>
<?php } ?>
<?php
} else {
?>
<th>#</th>
<th>Montant</th>
<th>Date</th>
<th>Caissier</th>
<th>Motif</th>
<th>Statut</th>
<th>Raison de validation</th>
<?php if (in_array('updateSortieCaisse', $user_permission)) { ?>
<th>Action</th>
<?php } ?>
<?php } ?>
</tr>
</thead>
</table>
</div>
</div>
<div class="row mb-3">
<div class="col-md-12">
<div class="btn-group float-right" role="group">
<a href="<?= base_url('sortieCaisse/exportExcel') ?>"
class="btn btn-success">
<i class="fa fa-file-excel-o"></i> Exporter Excel
</a>
<a href="<?= base_url('sortieCaisse/exportCsv') ?>"
class="btn btn-info">
<i class="fa fa-file-text-o"></i> Exporter CSV
</a>
</div>
</div>
</div>
<!-- Optionnel: Formulaire de filtres pour l'exportation -->
<div class="row mb-3">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h4>Exporter avec filtres</h4>
</div>
<div class="card-body">
<form id="exportFilterForm" class="form-inline">
<div class="form-group mr-2">
<label for="date_debut" class="mr-2">Date début:</label>
<input type="date" class="form-control" id="date_debut" name="date_debut">
</div>
<div class="form-group mr-2">
<label for="date_fin" class="mr-2">Date fin:</label>
<input type="date" class="form-control" id="date_fin" name="date_fin">
</div>
<div class="form-group mr-2">
<label for="statut" class="mr-2">Statut:</label>
<select class="form-control" id="statut" name="statut">
<option value="">Tous</option>
<option value="En attente">En attente</option>
<option value="Valider">Validé</option>
<option value="Refuser">Refusé</option>
</select>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-success" onclick="exportFiltered('excel')">
<i class="fa fa-file-excel-o"></i> Excel
</button>
<button type="button" class="btn btn-info" onclick="exportFiltered('csv')">
<i class="fa fa-file-text-o"></i> CSV
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<!-- Modal pour la Création -->
<?php if (in_array('createSortieCaisse', $user_permission)): ?>
<div class="modal fade" tabindex="-1" role="dialog" id="createModal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">Ajouter un décaissement</h4>
</div>
<form role="form" id="create_form_sortie" enctype="multipart/form-data">
<div class="modal-body">
<!-- FORMULAIRE IM1 (Décaissement simple) - CORRIGÉ -->
<div id="form-im1">
<div class="text-center" style="margin-bottom: 20px;">
<h3 style="border-bottom: 2px solid #333; padding-bottom: 10px;">DEMANDE DE SORTIE DE CAISSE</h3>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="nom" class="form-label">Nom</label>
<input type="text" class="form-control" id="nom" name="nom" placeholder="Votre nom" autocomplete="off" required>
</div>
<div class="col-md-6 mb-3">
<label for="fonction" class="form-label">Fonction</label>
<input type="text" class="form-control" id="fonction" name="fonction" placeholder="Votre fonction" autocomplete="off" required>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="motif_select" class="form-label">Motif</label>
<select class="form-control" id="motif_select" name="motif_select" required>
<?php
$session = session();
$users = $session->get('user');
$isAdmin = $users['group_name'] == "Direction" || $users['group_name'] == "Conseil";
$isCaissier = $users['group_name'] == "Caissière";
$options = $isAdmin ? $admin_options : $caissier_options;
foreach ($options as $option) {
echo "<option value=\"" . htmlspecialchars($option) . "\">" . htmlspecialchars($option) . "</option>\n";
}
?>
<option value="" selected>Veuillez sélectionner une raison</option>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="mode_paiement" class="form-label">Mode de paiement</label>
<select class="form-control" id="mode_paiement" name="mode_paiement" required>
<option value="En espèce">En espèce</option>
<option value="MVOLA">MVOLA</option>
<option value="Virement Bancaire">Virement Bancaire</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="montant_retire" class="form-label">Montant</label>
<!-- CORRECTION ICI : id ET name doivent être "montant_retire" -->
<input type="text" class="form-control" id="montant_retire" name="montant_retire" placeholder="Montant à retirer" autocomplete="off" required>
</div>
<div class="col-md-6 mb-3">
<label for="montant_lettre" class="form-label">Montant en lettre</label>
<input type="text" class="form-control" id="montant_lettre" name="montant_lettre" placeholder="Montant en toutes lettres" readonly>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="date_demande" class="form-label">Date</label>
<input type="date" class="form-control" id="date_demande" name="date_demande" required>
</div>
<div class="col-md-6 mb-3">
<label for="reference" class="form-label">Référence</label>
<input type="text" class="form-control" id="reference" name="reference" placeholder="Référence" autocomplete="off">
</div>
</div>
<div class="row text-center" style="margin-top: 30px;">
<div class="col-md-4">
<strong>DEMANDEUR</strong>
</div>
<div class="col-md-4">
<strong>DIRECTION</strong>
</div>
<div class="col-md-4">
<strong>CAISSE/COMPTA</strong>
</div>
</div>
</div>
<!-- FORMULAIRE IM2 et IM3 (Pour montant > 1,000,000 Ar) -->
<div id="form-im23" style="display: none;">
<!-- Bouton de retour -->
<div class="row mb-3">
<div class="col-md-12">
<button type="button" id="back-to-im1" class="btn btn-default btn-sm">
<i class="fa fa-arrow-left"></i> Retour à la demande simple
</button>
</div>
</div>
<div class="text-center" style="margin-bottom: 20px;">
<h3 style="border-bottom: 2px solid #333; padding-bottom: 10px;">FICHE D'ENGAGEMENT DE DEPENSE</h3>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="numero_fiche" class="form-label">N°</label>
<input type="text" class="form-control" id="numero_fiche" name="numero_fiche" placeholder="Numéro de fiche" autocomplete="off">
</div>
<div class="col-md-6 mb-3">
<label for="date_fiche" class="form-label">Date</label>
<input type="date" class="form-control" id="date_fiche" name="date_fiche">
</div>
</div>
<h4>I. IDENTIFICATION DE LA DEPENSE</h4>
<div class="row">
<div class="col-md-6 mb-3">
<label for="service_demandeur" class="form-label">Service demandeur</label>
<input type="text" class="form-control" id="service_demandeur" name="service_demandeur" placeholder="Service demandeur" autocomplete="off">
</div>
<div class="col-md-6 mb-3">
<label for="nom_demandeur" class="form-label">Nom du demandeur</label>
<input type="text" class="form-control" id="nom_demandeur" name="nom_demandeur" placeholder="Nom du demandeur" autocomplete="off">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="fonction_demandeur" class="form-label">Fonction</label>
<input type="text" class="form-control" id="fonction_demandeur" name="fonction_demandeur" placeholder="Fonction" autocomplete="off">
</div>
<div class="col-md-6 mb-3">
<label for="objet_depense" class="form-label">Objet de la dépense</label>
<textarea class="form-control" id="objet_depense" name="objet_depense" rows="2" placeholder="Objet de la dépense"></textarea>
</div>
</div>
<div class="row">
<div class="col-md-12 mb-3">
<label class="form-label">Nature de la dépense</label><br>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="nature_depense" id="achat_materiel" value="Achat matériel">
<label class="form-check-label" for="achat_materiel">Achat matériel</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="nature_depense" id="prestation_service" value="Prestation de service">
<label class="form-check-label" for="prestation_service">Prestation de service</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="nature_depense" id="frais_mission" value="Frais de mission / déplacement">
<label class="form-check-label" for="frais_mission">Frais de mission / déplacement</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="nature_depense" id="avance_fonds" value="Avance de fonds">
<label class="form-check-label" for="avance_fonds">Avance de fonds</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="nature_depense" id="autre_nature" value="Autre">
<label class="form-check-label" for="autre_nature">Autres (à préciser)</label>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="montant_estime" class="form-label">Montant estimatif (en ariary)</label>
<input type="text" class="form-control" id="montant_estime" name="montant_estime" placeholder="Montant estimatif" autocomplete="off">
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Mode de règlement</label><br>
<div class="form-check">
<input class="form-check-input" type="radio" name="mode_reglement" id="espece" value="En espèce">
<label class="form-check-label" for="espece">En espèce</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="mode_reglement" id="virement" value="Virement Bancaire">
<label class="form-check-label" for="virement">Virement Bancaire</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="mode_reglement" id="mvola" value="MVOLA">
<label class="form-check-label" for="mvola">MVOLA</label>
</div>
</div>
<div class="col-md-4 mb-3">
<label for="date_paiement_prevue" class="form-label">Date prévue de paiement</label>
<input type="date" class="form-control" id="date_paiement_prevue" name="date_paiement_prevue">
</div>
</div>
<h4>II. JUSTIFICATIFS</h4>
<div class="row">
<div class="col-md-12 mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="devis_facture" name="justificatifs[]" value="Devis / facture pro forma">
<label class="form-check-label" for="devis_facture">Devis / facture pro forma</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="contrat_commande" name="justificatifs[]" value="Contrat / bon de commande">
<label class="form-check-label" for="contrat_commande">Contrat / bon de commande</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="demande_interne" name="justificatifs[]" value="Demande interne">
<label class="form-check-label" for="demande_interne">Demande interne</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="autre_justificatif" name="justificatifs[]" value="Autre">
<label class="form-check-label" for="autre_justificatif">Autre :</label>
<input type="text" class="form-control mt-1" id="autre_justificatif_precis" name="autre_justificatif_precis" placeholder="Préciser">
</div>
</div>
</div>
<h4>III. VISAS ET VALIDATIONS</h4>
<table class="table table-bordered">
<thead>
<tr>
<th>Fonction</th>
<th>Nom et signature</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>Demandeur</td>
<td><input type="text" class="form-control" name="visa_demandeur" placeholder="Nom et signature"></td>
<td><input type="date" class="form-control" name="date_visa_demandeur"></td>
</tr>
<tr>
<td>Chef de service / Responsable hiérarchique</td>
<td><input type="text" class="form-control" name="visa_chef_service" placeholder="Nom et signature"></td>
<td><input type="date" class="form-control" name="date_visa_chef_service"></td>
</tr>
<tr>
<td>Direction</td>
<td><input type="text" class="form-control" name="visa_direction" placeholder="Nom et signature"></td>
<td><input type="date" class="form-control" name="date_visa_direction"></td>
</tr>
<tr>
<td>Conseil d'Administration</td>
<td><input type="text" class="form-control" name="visa_conseil" placeholder="Nom et signature"></td>
<td><input type="date" class="form-control" name="date_visa_conseil"></td>
</tr>
</tbody>
</table>
<h4>IV. OBSERVATIONS ET REMARQUES</h4>
<div class="row">
<div class="col-md-12 mb-3">
<textarea class="form-control" id="observations" name="observations" rows="3" placeholder="Observations et remarques"></textarea>
</div>
</div>
<div class="alert alert-info">
<strong>NB :</strong> Cette fiche doit être jointe à la demande de sortie de caisse pour toute dépense supérieure à 1 000 000 Ar ou toute dépense nécessitant une traçabilité spécifique
</div>
</div>
</div>
<div class="modal-footer text-right" style="margin-top: 15px;">
<button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>
<button type="submit" class="btn btn-primary">Enregistrer</button>
</div>
</form>
</div>
</div>
</div>
<?php endif; ?>
<!-- Modal for updatting a recouvrement -->
<!-- Modal for updating a sortie caisse --><!-- Modal for updating a sortie caisse -->
<?php if (in_array('updateSortieCaisse', $user_permission)): ?>
<div class="modal fade" tabindex="-1" role="dialog" id="updateModal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title"><i class="fa fa-pencil"></i> Modifier un décaissement</h4>
</div>
<form role="form" id="update_form" enctype="multipart/form-data">
<div class="modal-body">
<!-- Légende des champs -->
<div class="field-legend">
<div>
<strong><i class="fa fa-info-circle"></i> Légende :</strong>
</div>
<div class="legend-item">
<i class="fa fa-lock text-muted"></i> Champs verrouillés (lecture seule)
</div>
<div class="legend-item">
<i class="fa fa-edit text-primary"></i> Champs modifiables
</div>
</div>
<!-- Informations de base - VERROUILLÉES -->
<div class="row">
<div class="col-md-6 mb-3">
<label for="nom_edit" class="form-label"><i class="fa fa-lock text-muted"></i> Nom</label>
<input type="text" class="form-control" id="nom_edit" name="nom_edit" placeholder="Votre nom" autocomplete="off" required readonly style="background-color: #e9ecef; cursor: not-allowed;">
</div>
<div class="col-md-6 mb-3">
<label for="fonction_edit" class="form-label"><i class="fa fa-lock text-muted"></i> Fonction</label>
<input type="text" class="form-control" id="fonction_edit" name="fonction_edit" placeholder="Votre fonction" autocomplete="off" required readonly style="background-color: #e9ecef; cursor: not-allowed;">
</div>
</div>
<!-- Motif et Mode de paiement -->
<div class="row">
<div class="col-md-6 mb-3">
<label for="motif_select_edit" class="form-label"><i class="fa fa-lock text-muted"></i> Motif</label>
<select class="form-control" id="motif_select_edit" name="motif_select_edit" required disabled style="background-color: #e9ecef; cursor: not-allowed;">
<?php
$session = session();
$users = $session->get('user');
$isAdmin = $users['group_name'] == "Direction" || $users['group_name'] == "Conseil";
$options = $isAdmin ? $admin_options : $caissier_options;
foreach ($options as $option) {
echo "<option value=\"" . htmlspecialchars($option) . "\">" . htmlspecialchars($option) . "</option>\n";
}
?>
<option value="" selected>Veuillez sélectionner une raison</option>
</select>
<!-- Champ caché pour envoyer la valeur du motif -->
<input type="hidden" id="motif_select_edit_hidden" name="motif_select_edit">
</div>
<div class="col-md-6 mb-3">
<label for="mode_paiement_edit" class="form-label"><i class="fa fa-edit text-primary"></i> Mode de paiement</label>
<select class="form-control" id="mode_paiement_edit" name="mode_paiement_edit" required>
<option value="En espèce">En espèce</option>
<option value="MVOLA">MVOLA</option>
<option value="Virement Bancaire">Virement Bancaire</option>
</select>
<small class="text-muted"><i class="fa fa-info-circle"></i> Assurez-vous que les fonds sont disponibles pour ce mode</small>
</div>
</div>
<!-- Montant - VERROUILLÉ -->
<div class="row">
<div class="col-md-6 mb-3">
<label for="montant_retire_edit" class="form-label"><i class="fa fa-lock text-muted"></i> Montant</label>
<input type="text" class="form-control" id="montant_retire_edit" name="montant_retire_edit" placeholder="Montant à retirer" autocomplete="off" required readonly style="background-color: #e9ecef; cursor: not-allowed;">
</div>
<div class="col-md-6 mb-3">
<label for="montant_lettre_edit" class="form-label"><i class="fa fa-lock text-muted"></i> Montant en lettre</label>
<input type="text" class="form-control" id="montant_lettre_edit" name="montant_lettre_edit" placeholder="Montant en toutes lettres" autocomplete="off" required readonly style="background-color: #e9ecef; cursor: not-allowed;">
</div>
</div>
<!-- Date et Référence - VERROUILLÉES -->
<div class="row">
<div class="col-md-6 mb-3">
<label for="date_demande_edit" class="form-label"><i class="fa fa-lock text-muted"></i> Date</label>
<input type="date" class="form-control" id="date_demande_edit" name="date_demande_edit" required readonly style="background-color: #e9ecef; cursor: not-allowed;">
</div>
<div class="col-md-6 mb-3">
<label for="reference_edit" class="form-label"><i class="fa fa-lock text-muted"></i> Référence</label>
<input type="text" class="form-control" id="reference_edit" name="reference_edit" placeholder="Référence" autocomplete="off" readonly style="background-color: #e9ecef; cursor: not-allowed;">
</div>
</div>
<hr style="border-top: 2px dashed #007bff; margin: 25px 0;">
<h5 style="color: #007bff; margin-bottom: 15px;"><i class="fa fa-edit"></i> Informations modifiables</h5>
<!-- Commentaire - ÉDITABLE -->
<div class="row">
<div class="col-md-12 mb-3">
<label for="sortie_commentaire_edit" class="form-label">
<i class="fa fa-edit text-primary"></i> Commentaire
</label>
<textarea class="form-control" id="sortie_commentaire_edit" name="sortie_commentaire_edit" rows="3" style="resize: vertical;" placeholder="Votre commentaire" autocomplete="off"></textarea>
</div>
</div>
<!-- Informations fournisseur - ÉDITABLES -->
<div class="row">
<div class="col-md-4 mb-3">
<label for="sortie_fournisseur_edit" class="form-label">
<i class="fa fa-edit text-primary"></i> Fournisseur & Prestataire
</label>
<input type="text" class="form-control" id="sortie_fournisseur_edit" name="sortie_fournisseur_edit" placeholder="Entrer le fournisseur ou le prestataire" autocomplete="off">
</div>
<div class="col-md-4 mb-3">
<label for="sortie_nif_edit" class="form-label">
<i class="fa fa-edit text-primary"></i> NIF & CIN
</label>
<input type="text" class="form-control" id="sortie_nif_edit" name="sortie_nif_edit" placeholder="NIF ou CIN" autocomplete="off">
</div>
<div class="col-md-4 mb-3">
<label for="sortie_statistique_edit" class="form-label">
<i class="fa fa-edit text-primary"></i> Statistique
</label>
<input type="text" class="form-control" id="sortie_statistique_edit" name="sortie_statistique_edit" placeholder="Statistique du décaissement" autocomplete="off">
</div>
</div>
<!-- Coordonnées - ÉDITABLES -->
<div class="row">
<div class="col-md-4 mb-3">
<label for="sortie_phone_edit" class="form-label">
<i class="fa fa-edit text-primary"></i> Numéro téléphone
</label>
<input type="text" class="form-control" id="sortie_phone_edit" name="sortie_phone_edit" placeholder="Entrer le numéro de téléphone" autocomplete="off">
</div>
<div class="col-md-4 mb-3">
<label for="sortie_adresse_edit" class="form-label">
<i class="fa fa-edit text-primary"></i> Code postal
</label>
<input type="text" class="form-control" id="sortie_adresse_edit" name="sortie_adresse_edit" placeholder="Entrer le code postal" autocomplete="off">
</div>
<div class="col-md-4 mb-3">
<label for="sortie_preuve_edit" class="form-label">
<i class="fa fa-edit text-primary"></i> Preuve d'achat
<small class="text-muted">(Facultatif)</small>
</label>
<input type="file" accept=".pdf, .txt, .xls, .xlsx, .csv" class="form-control" id="sortie_preuve_edit" name="sortie_preuve_edit">
<small class="text-muted" id="current_preuve_text"></small>
</div>
</div>
</div>
<div class="modal-footer text-right" style="margin-top: 15px;">
<button type="button" class="btn btn-default" data-dismiss="modal">
<i class="fa fa-times"></i> Annuler
</button>
<button type="submit" class="btn btn-primary">
<i class="fa fa-save"></i> Enregistrer les modifications
</button>
</div>
</form>
</div>
</div>
</div>
<?php endif; ?>
<!-- Modal for validating a recouvrement -->
<?php if (in_array('validateSortieCaisse', $user_permission)): ?>
<div class="modal fade" tabindex="-1" role="dialog" id="validateModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Valider un décaissement</h4>
</div>
<form role="form" action="<?php echo base_url('sortieCaisse/validateSortieCaisse') ?>" method="post" id="validate_form">
<div class="modal-body">
<div class="row form-group">
<div class="col-lg-6">
<label for="validation" class="control-label">statut :</label>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="admin_raison">Raison de validation</label>
<input type="text" class="form-control" id="admin_raison" name="admin_raison">
</div>
<div class="form-group">
<label for="statut">Statut du décaissement</label>
<select name="statut" id="statut" class="form-control">
<option value="En attente" selected>En attente</option>
<option value="Valider">✔ Valider</option>
<option value="Refuser">✖ Refuser</option>
</select>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>
<button type="submit" class="btn btn-primary">Enregistrer</button>
</div>
</form>
</div>
</div>
</div>
<?php endif; ?>
<script>
// ============================================
// CONVERSION NOMBRE EN LETTRES (FRANÇAIS)
// ============================================
function numberToFrenchWords(n) {
const units = [
'', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf',
'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize',
'dix-sept', 'dix-huit', 'dix-neuf'
];
const tens = [
'', '', 'vingt', 'trente', 'quarante', 'cinquante',
'soixante', 'soixante', 'quatre-vingt', 'quatre-vingt'
];
if (n === 0) return 'zéro';
if (n < 0) return 'moins ' + numberToFrenchWords(-n);
let words = '';
if (Math.floor(n / 1000000000) > 0) {
words += numberToFrenchWords(Math.floor(n / 1000000000)) + ' milliard' + (n >= 2000000000 ? 's ' : ' ');
n %= 1000000000;
}
if (Math.floor(n / 1000000) > 0) {
words += numberToFrenchWords(Math.floor(n / 1000000)) + ' million' + (n >= 2000000 ? 's ' : ' ');
n %= 1000000;
}
if (Math.floor(n / 1000) > 0) {
if (Math.floor(n / 1000) === 1) {
words += 'mille ';
} else {
words += numberToFrenchWords(Math.floor(n / 1000)) + ' mille ';
}
n %= 1000;
}
if (Math.floor(n / 100) > 0) {
if (Math.floor(n / 100) === 1) {
words += 'cent ';
} else {
words += numberToFrenchWords(Math.floor(n / 100)) + ' cent';
if (n % 100 === 0) words += 's';
words += ' ';
}
n %= 100;
}
if (n > 0) {
if (n < 20) {
words += units[n];
} else {
let ten = Math.floor(n / 10);
let unit = n % 10;
if (ten === 7 || ten === 9) {
ten--;
unit += 10;
}
words += tens[ten];
if (unit === 1 && (ten === 1 || (ten > 1 && ten < 8))) {
words += '-et-un';
} else if (unit > 0) {
words += '-' + units[unit];
}
if (ten === 8 && unit === 0) words += 's';
}
}
return words.trim();
}
// ============================================
// FORMATAGE PAR GROUPE DE 3
// ============================================
function formatNumberBy3(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
}
// ============================================
// FONCTION D'EXPORTATION FILTRÉE
// ============================================
function exportFiltered(format) {
const dateDebut = document.getElementById('date_debut').value;
const dateFin = document.getElementById('date_fin').value;
const statut = document.getElementById('statut').value;
let url = '<?= base_url('sortieCaisse/exportWithFilters') ?>?format=' + format;
if (dateDebut) url += '&date_debut=' + dateDebut;
if (dateFin) url += '&date_fin=' + dateFin;
if (statut) url += '&statut=' + encodeURIComponent(statut);
window.location.href = url;
}
// ============================================
// SCRIPT PRINCIPAL
// ============================================
$(document).ready(function() {
// Configuration DataTable FR
$.extend(true, $.fn.dataTable.defaults, {
language: {
sProcessing: "Traitement en cours...",
sSearch: "Rechercher&nbsp;:",
sLengthMenu: "Afficher _MENU_ &eacute;l&eacute;ments",
sInfo: "Affichage de l'&eacute;lement _START_ &agrave; _END_ sur _TOTAL_ &eacute;l&eacute;ments",
sInfoEmpty: "Affichage de l'&eacute;lement 0 &agrave; 0 sur 0 &eacute;l&eacute;ment",
sInfoFiltered: "(filtr&eacute; de _MAX_ &eacute;l&eacute;ments au total)",
sLoadingRecords: "Chargement en cours...",
sZeroRecords: "Aucun &eacute;l&eacute;ment &agrave; afficher",
sEmptyTable: "Aucune donn&eacute;e disponible dans le tableau",
oPaginate: {
sFirst: "Premier",
sPrevious: "Pr&eacute;c&eacute;dent",
sNext: "Suivant",
sLast: "Dernier"
},
oAria: {
sSortAscending: ": activer pour trier la colonne par ordre croissant",
sSortDescending: ": activer pour trier la colonne par ordre d&eacute;croissant"
}
}
});
$("#sortie_caisse_menu").addClass('active');
var manageTable = $('#manageTable').DataTable({
ajax: '<?= base_url('sortieCaisse/fetchSortieCaisseData') ?>',
order: [],
columnDefs: [
{ targets: 1, className: 'text-right rowmontant' }
]
});
// ============================================
// INITIALISATION DES DATES
// ============================================
const today = new Date().toISOString().split('T')[0];
$('#date_demande').val(today);
$('#date_fiche').val(today);
// ============================================
// GESTION DU MONTANT ET CONVERSION EN LETTRES
// ============================================
const montantInput = $('#montant_retire');
const montantLettreInput = $('#montant_lettre');
montantInput.on('input', function() {
let value = this.value.replace(/\s/g, '');
if (isNaN(value) || value === '') {
montantLettreInput.val('');
return;
}
const num = parseInt(value, 10);
this.value = formatNumberBy3(value);
const words = numberToFrenchWords(num);
montantLettreInput.val(words + ' ariary');
// Gestion du basculement de formulaire
if (num > 1000000) {
$('#nom_demandeur').val($('#nom').val());
$('#fonction_demandeur').val($('#fonction').val());
$('#montant_estime').val(this.value);
$('#date_fiche').val($('#date_demande').val());
$('#form-im1').hide();
$('#form-im23').show();
} else {
$('#form-im1').show();
$('#form-im23').hide();
}
});
// Retour au formulaire simple
$('#back-to-im1').on('click', function() {
$('#form-im23').hide();
$('#form-im1').show();
montantInput.val('500000');
montantInput.trigger('input');
});
// Synchronisation des montants
montantInput.on('change', function() {
$('#montant_estime').val($(this).val());
});
$('#montant_estime').on('change', function() {
montantInput.val($(this).val());
montantInput.trigger('input');
});
// Réinitialisation du modal
$('#createModal').on('hidden.bs.modal', function () {
$('#form-im1').show();
$('#form-im23').hide();
$('#create_form_sortie')[0].reset();
$('#date_demande').val(today);
$('#date_fiche').val(today);
montantLettreInput.val('');
});
// ============================================
// FILTRES
// ============================================
$('#filteredB1').on('click', function () {
const startDate = $('#startDate').val();
const endDate = $('#endDate').val();
const pvente = $('#pvente').val();
const s_statut = $('#s_statut').val();
manageTable.ajax.url('<?= base_url('sortieCaisse/fetchSortieCaisseData') ?>').load(function () {
const filteredData = [];
manageTable.rows().every(function () {
const data = this.data();
const SortieDate = data[2].split(' ')[0];
<?php
$session = session();
$users = $session->get('user');
$isAdmin = $users['group_name'] == "Direction" || $users['group_name'] == "Conseil";
?>
<?php if($isAdmin): ?>
const sortie_statut1 = data[9].split(' ')[0];
const store = data[7];
<?php else: ?>
const sortie_statut1 = data[5].split(' ')[0];
const store = 'TOUS';
<?php endif; ?>
const dateMatch = (!startDate && !endDate) ||
(startDate && endDate && SortieDate >= startDate && SortieDate <= endDate) ||
(startDate && !endDate && SortieDate >= startDate) ||
(!startDate && endDate && SortieDate <= endDate);
const storeMatch = (pvente === 'TOUS' || pvente === store);
const statutMatch = (s_statut === 'TOUS' || s_statut === sortie_statut1);
if (dateMatch && storeMatch && statutMatch) {
filteredData.push(data);
}
});
manageTable.clear().rows.add(filteredData).draw();
});
});
$('#validate_filtered').on('click', function () {
manageTable.ajax.url('<?= base_url('sortieCaisse/fetchSortieCaisseData1') ?>').load();
});
// ============================================
// CRÉATION AVEC SWEETALERT2 - CORRIGÉ
// ============================================
$("#create_form_sortie").unbind('submit').on('submit', function(e) {
e.preventDefault();
$(".text-danger").remove();
var formData = new FormData(this);
// CORRECTION : Nettoyer le montant des espaces avant validation
const montantRaw = $('#montant_retire').val();
const montantClean = montantRaw.replace(/\s/g, '');
// Vérification du montant avant l'envoi
const montant = parseFloat(montantClean);
if (isNaN(montant) || montant <= 0) {
Swal.fire({
icon: 'error',
title: 'Montant invalide',
text: 'Veuillez saisir un montant valide supérieur à 0',
confirmButtonColor: '#dc3545'
});
return false;
}
// CORRECTION : Remplacer la valeur dans le FormData
formData.set('montant_retire', montantClean);
// Afficher un loader
Swal.fire({
title: 'Création en cours...',
html: 'Vérification des fonds disponibles...',
allowOutsideClick: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
$.ajax({
url: '<?= base_url('sortieCaisse/createSortieCaisse') ?>',
type: 'post',
data: formData,
processData: false,
contentType: false,
dataType: 'json',
success: function(response) {
manageTable.ajax.reload(null, false);
if (response.success === true) {
Swal.fire({
icon: 'success',
title: 'Décaissement créé !',
html: response.messages,
confirmButtonText: 'Fermer',
confirmButtonColor: '#28a745',
customClass: {
popup: 'animated fadeInDown'
}
}).then(() => {
$("#createModal").modal('hide');
$("#create_form_sortie")[0].reset();
$("#create_form_sortie .form-group").removeClass('has-error has-success');
$('#date_demande').val(today);
$('#date_fiche').val(today);
});
} else {
// Gestion des erreurs avec SweetAlert
if (response.messages instanceof Object) {
let errorHtml = '<ul style="text-align: left; margin: 10px 0;">';
$.each(response.messages, function(index, value) {
errorHtml += '<li style="margin: 5px 0;">' + value + '</li>';
var id = $("#" + index);
id.closest('.form-group')
.removeClass('has-error has-success')
.addClass('has-error');
id.after('<span class="text-danger">' + value + '</span>');
});
errorHtml += '</ul>';
Swal.fire({
icon: 'warning',
title: 'Erreurs de validation',
html: errorHtml,
confirmButtonText: 'Corriger',
confirmButtonColor: '#f39c12',
customClass: {
popup: 'animated shake'
}
});
} else {
// Affichage amélioré pour les erreurs de fonds insuffisants
const isInsufficientFunds = response.messages.includes('insuffisants');
Swal.fire({
icon: isInsufficientFunds ? 'warning' : 'error',
title: isInsufficientFunds ? '⚠️ Fonds insuffisants' : 'Erreur',
html: '<div style="text-align: left;">' + response.messages + '</div>',
confirmButtonText: 'Fermer',
confirmButtonColor: isInsufficientFunds ? '#f39c12' : '#dc3545',
width: '600px',
customClass: {
popup: 'animated fadeInDown'
}
});
}
}
},
error: function(xhr, status, error) {
console.error('Erreur AJAX:', error);
Swal.fire({
icon: 'error',
title: 'Erreur serveur',
html: '<p>Une erreur est survenue lors de la création du décaissement.</p>' +
'<p><small>Détails techniques: ' + error + '</small></p>',
confirmButtonText: 'Fermer',
confirmButtonColor: '#dc3545'
});
}
});
return false;
});
// ============================================
// MODIFICATION AVEC SWEETALERT2 - CORRIGÉ
// ============================================
window.editFunc = function(id) {
$.ajax({
url: '<?= base_url('sortieCaisse/fetchSortieCaisseSingle') ?>/' + id,
type: 'post',
dataType: 'json',
success: function(response) {
// Remplir tous les champs
$("#montant_retire_edit").val(response.montant_retire);
$("#nom_edit").val(response.nom_demandeur);
$("#fonction_edit").val(response.fonction_demandeur);
$("#montant_lettre_edit").val(response.montant_lettre);
$("#date_demande_edit").val(response.date_demande);
$("#reference_edit").val(response.reference);
$("#sortie_commentaire_edit").val(response.commentaire);
$("#sortie_fournisseur_edit").val(response.fournisseur);
$("#sortie_nif_edit").val(response.nif_cin);
$("#sortie_statistique_edit").val(response.statistique);
$("#sortie_phone_edit").val(response.telephone);
$("#sortie_adresse_edit").val(response.code_postal);
const initialModePaiement = response.mode_paiement || 'En espèce';
$("#mode_paiement_edit").val(initialModePaiement);
// Gérer le motif
const motif = response.motif;
const motifSelect = $("#motif_select_edit");
const optionExists = motifSelect.find('option').filter(function() {
return $(this).val().trim().toLowerCase() === motif.trim().toLowerCase();
}).length > 0;
if (optionExists) {
motifSelect.val(motif);
} else {
motifSelect.val("");
}
$("#motif_select_edit_hidden").val(motif);
if (response.preuve_achat) {
$("#current_preuve_text").html('<br><i class="fa fa-file"></i> Fichier actuel: ' + response.preuve_achat);
} else {
$("#current_preuve_text").html('<br><i class="text-muted">Aucun fichier</i>');
}
// Listener sur le mode de paiement
$("#mode_paiement_edit").off('change').on('change', function() {
const nouveauMode = $(this).val();
if (nouveauMode !== initialModePaiement) {
Swal.fire({
icon: 'warning',
title: 'Changement de mode de paiement',
html: '<div style="text-align: center;">' +
'<strong>Attention !</strong><br><br>' +
'Vous changez le mode de paiement :<br><br>' +
'<span style="font-size: 18px;">' +
'<span style="color: #dc3545; font-weight: bold;">' + initialModePaiement + '</span>' +
' <i class="fa fa-arrow-right"></i> ' +
'<span style="color: #28a745; font-weight: bold;">' + nouveauMode + '</span>' +
'</span><br><br>' +
'<em style="color: #856404;">Assurez-vous que les fonds sont disponibles.</em>' +
'</div>',
showCancelButton: true,
confirmButtonText: '<i class="fa fa-check"></i> Confirmer',
cancelButtonText: '<i class="fa fa-times"></i> Annuler',
confirmButtonColor: '#007bff',
cancelButtonColor: '#6c757d'
}).then((result) => {
if (!result.isConfirmed) {
$("#mode_paiement_edit").val(initialModePaiement);
}
});
}
});
// Soumission du formulaire - CORRIGÉ
$("#update_form").unbind('submit').bind('submit', function(e) {
e.preventDefault();
$(".text-danger").remove();
var formData = new FormData(this);
// CORRECTION : Nettoyer le montant des espaces pour l'édition
const montantRawEdit = $('#montant_retire_edit').val();
const montantCleanEdit = montantRawEdit.replace(/\s/g, '');
formData.set('montant_retire', montantCleanEdit);
Swal.fire({
title: 'Modification en cours...',
html: 'Vérification des fonds disponibles...',
allowOutsideClick: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
$.ajax({
url: '<?= base_url('sortieCaisse/updateSortieCaisse') ?>/' + id,
type: 'post',
data: formData,
processData: false,
contentType: false,
dataType: 'json',
success: function(response) {
manageTable.ajax.reload(null, false);
if (response.success === true) {
Swal.fire({
icon: 'success',
title: 'Modification réussie !',
html: response.messages,
confirmButtonText: 'Fermer',
confirmButtonColor: '#28a745'
}).then(() => {
$("#updateModal").modal('hide');
$("#update_form")[0].reset();
});
} else {
if (response.messages instanceof Object) {
let errorHtml = '<ul style="text-align: left;">';
$.each(response.messages, function(index, value) {
errorHtml += '<li>' + value + '</li>';
var input = $("#" + index);
input.closest('.form-group').addClass('has-error');
input.after('<span class="text-danger">' + value + '</span>');
});
errorHtml += '</ul>';
Swal.fire({
icon: 'warning',
title: 'Erreur de validation',
html: errorHtml,
confirmButtonText: 'Corriger',
confirmButtonColor: '#f39c12'
});
} else {
const isInsufficientFunds = response.messages.includes('insuffisants');
Swal.fire({
icon: isInsufficientFunds ? 'warning' : 'error',
title: isInsufficientFunds ? '⚠️ Fonds insuffisants' : 'Erreur',
html: '<div style="text-align: left;">' + response.messages + '</div>',
confirmButtonText: 'Fermer',
confirmButtonColor: isInsufficientFunds ? '#f39c12' : '#dc3545',
width: '600px'
});
}
}
},
error: function(xhr, status, error) {
Swal.fire({
icon: 'error',
title: 'Erreur serveur',
text: 'Une erreur est survenue lors de la modification.',
confirmButtonText: 'Fermer',
confirmButtonColor: '#dc3545'
});
}
});
return false;
});
},
error: function(xhr, status, error) {
Swal.fire({
icon: 'error',
title: 'Erreur',
text: 'Impossible de récupérer les données du décaissement',
confirmButtonText: 'Fermer',
confirmButtonColor: '#dc3545'
});
}
});
};
// ============================================
// VALIDATION
// ============================================
window.validateFunc = function(id) {
$.ajax({
url: '<?= base_url('sortieCaisse/fetchSortieCaisseSingle') ?>/' + id,
type: 'post',
dataType: 'json',
success: function(response) {
var statut = response.statut;
if (statut === "En attente" || statut === "Refuser") {
$("#statut").val(response.statut);
$("#admin_raison").val(response.admin_raison);
$("#validateModal").modal('show');
$("#validate_form").unbind('submit').bind('submit', function(e) {
e.preventDefault();
$(".text-danger").remove();
$.ajax({
url: '<?= base_url('sortieCaisse/validateSortieCaisse') ?>/' + id,
type: 'post',
data: $(this).serialize(),
dataType: 'json',
success: function(response) {
manageTable.ajax.reload(null, false);
if (response.success === true) {
$("#messages").html('<div class="alert alert-success alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert">&times;</button>' +
'<strong><span class="glyphicon glyphicon-ok-sign"></span></strong> ' + response.messages +
'</div>');
$("#validateModal").modal('hide');
$("#validate_form .form-group").removeClass('has-error has-success');
} else {
if (typeof response.messages === 'object') {
$.each(response.messages, function(index, value) {
var input = $("#" + index);
input.closest('.form-group')
.removeClass('has-error has-success')
.addClass(value.length > 0 ? 'has-error' : 'has-success');
input.after('<span class="text-danger">' + value + '</span>');
});
} else {
$("#messages").html('<div class="alert alert-warning alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert">&times;</button>' +
'<strong><span class="glyphicon glyphicon-exclamation-sign"></span></strong> ' + response.messages +
'</div>');
}
}
},
error: function(xhr, status, error) {
Swal.fire({
icon: 'error',
title: 'Erreur',
text: 'Une erreur est survenue lors de la validation.',
confirmButtonText: 'Fermer',
confirmButtonColor: '#dc3545'
});
}
});
});
} else {
Swal.fire({
icon: 'info',
title: 'Déjà validé',
html: '<p style="font-size: 16px;">Ce décaissement est déjà validé et ne peut pas être modifié.</p>',
confirmButtonText: 'Fermer',
confirmButtonColor: '#17a2b8',
width: '500px'
});
}
},
error: function() {
Swal.fire({
icon: 'error',
title: 'Erreur',
text: 'Une erreur est survenue lors de la récupération des données.',
confirmButtonText: 'OK'
});
}
});
};
});
window.markAsPaidFunc = function(id_sortie) {
Swal.fire({
title: '💰 Confirmer le paiement',
html: '<div style="text-align: center;">' +
'<p style="font-size: 16px; margin: 20px 0;">Êtes-vous sûr(e) de vouloir marquer ce décaissement comme <strong>PAYÉ</strong> ?</p>' +
'<div style="background-color: #fff3cd; padding: 15px; border-radius: 5px; border-left: 4px solid #ffc107; margin-top: 15px;">' +
'<i class="fa fa-info-circle" style="color: #856404;"></i> ' +
'<strong style="color: #856404;">Cette action va :</strong><br>' +
'<ul style="text-align: left; margin-top: 10px; color: #856404;">' +
'<li>Changer le statut de "Validé" à "Payé"</li>' +
'<li>Notifier la Direction et le DAF</li>' +
'<li>Enregistrer la date de paiement</li>' +
'</ul>' +
'</div>' +
'</div>',
icon: 'question',
showCancelButton: true,
confirmButtonColor: '#28a745',
cancelButtonColor: '#6c757d',
confirmButtonText: '<i class="fa fa-check"></i> Oui, marquer comme payé',
cancelButtonText: '<i class="fa fa-times"></i> Annuler',
customClass: {
popup: 'animated fadeInDown'
}
}).then((result) => {
if (result.isConfirmed) {
// Afficher un loader
Swal.fire({
title: 'Traitement en cours...',
html: 'Mise à jour du statut et envoi des notifications...',
allowOutsideClick: false,
allowEscapeKey: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
// Envoi de la requête AJAX
$.ajax({
url: '<?= base_url('sortieCaisse/markAsPaid') ?>/' + id_sortie,
type: 'POST',
dataType: 'json',
success: function(response) {
if (response.success === true) {
// ✅ SUCCÈS : Afficher le message puis actualiser
Swal.fire({
icon: 'success',
title: 'Paiement enregistré !',
html: response.messages + '<br><br><em>La page va se recharger...</em>',
confirmButtonText: 'OK',
confirmButtonColor: '#28a745',
timer: 2500,
timerProgressBar: true,
allowOutsideClick: false,
customClass: {
popup: 'animated bounceIn'
}
}).then(() => {
// ✅ ACTUALISER LA PAGE
location.reload();
});
} else {
// ❌ ERREUR : Afficher le message puis actualiser
Swal.fire({
icon: 'error',
title: 'Erreur',
html: response.messages + '<br><br><em>La page va se recharger...</em>',
confirmButtonText: 'Fermer',
confirmButtonColor: '#dc3545',
timer: 3000,
timerProgressBar: true,
allowOutsideClick: false,
customClass: {
popup: 'animated shake'
}
}).then(() => {
// ✅ ACTUALISER LA PAGE MÊME EN CAS D'ERREUR
location.reload();
});
}
},
error: function(xhr, status, error) {
console.error('Erreur AJAX markAsPaid:', error);
console.error('Réponse complète:', xhr.responseText);
// ❌ ERREUR SERVEUR : Afficher puis actualiser
Swal.fire({
icon: 'error',
title: 'Erreur serveur',
html: '<p>Une erreur est survenue lors du changement de statut.</p>' +
'<p><small>Détails : ' + error + '</small></p>' +
'<br><em>La page va se recharger...</em>',
confirmButtonText: 'Fermer',
confirmButtonColor: '#dc3545',
timer: 3000,
timerProgressBar: true,
allowOutsideClick: false
}).then(() => {
// ✅ ACTUALISER LA PAGE
location.reload();
});
}
});
}
});
};
</script>