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.
743 lines
24 KiB
743 lines
24 KiB
<!-- application/Views/securite/history.php -->
|
|
<style>
|
|
.validation-summary {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
border-radius: 15px;
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
|
|
overflow: hidden;
|
|
margin: 20px 0;
|
|
}
|
|
|
|
.validation-summary .box-header {
|
|
background: rgba(255, 255, 255, 0.95);
|
|
border-bottom: 3px solid #667eea;
|
|
padding: 20px 25px;
|
|
}
|
|
|
|
.validation-summary .box-title {
|
|
color: #667eea;
|
|
font-size: 22px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.validation-summary .box-body {
|
|
background: #ffffff;
|
|
padding: 35px 25px;
|
|
}
|
|
|
|
.stat-card {
|
|
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
|
|
border-radius: 12px;
|
|
padding: 25px 15px;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
overflow: hidden;
|
|
border-left: 5px solid #2196f3;
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-card:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.stat-number {
|
|
font-size: 36px;
|
|
font-weight: 800;
|
|
color: #1976d2;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
color: #1565c0;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.badge-validated {
|
|
background-color: #4caf50;
|
|
color: white;
|
|
padding: 5px 10px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.table-responsive {
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
|
}
|
|
|
|
#historyTable thead {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
}
|
|
|
|
#historyTable thead th {
|
|
border: none !important;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
font-size: 13px;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
#historyTable tbody tr {
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
#historyTable tbody tr:hover {
|
|
background-color: #f5f5f5;
|
|
transform: scale(1.01);
|
|
}
|
|
|
|
.moto-image {
|
|
width: 80px;
|
|
height: 60px;
|
|
object-fit: cover;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.agent-name {
|
|
color: #667eea;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.validation-date {
|
|
color: #6c757d;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.filter-section {
|
|
background: #f8f9fa;
|
|
padding: 20px;
|
|
border-radius: 10px;
|
|
margin-bottom: 20px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
}
|
|
</style>
|
|
|
|
<div class="content-wrapper">
|
|
<!-- Content Header -->
|
|
<section class="content-header">
|
|
<h1>
|
|
Historique des Livraisons
|
|
<small>Suivi des sorties validées par magasin</small>
|
|
</h1>
|
|
<ol class="breadcrumb">
|
|
<li><a href="<?= base_url('#') ?>"><i class="fa fa-dashboard"></i> Accueil</a></li>
|
|
<li><a href="<?= base_url('validateSecurite') ?>"><i class="fa fa-shield"></i> Livraisons</a></li>
|
|
<li class="active">Historique</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<!-- Main content -->
|
|
<section class="content">
|
|
<div id="messages"></div>
|
|
|
|
<?php if (session()->getFlashdata('success')): ?>
|
|
<div class="alert alert-success alert-dismissible">
|
|
<button type="button" class="close" data-dismiss="alert">×</button>
|
|
<?= session()->getFlashdata('success') ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Statistiques -->
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="validation-summary">
|
|
<div class="box-header">
|
|
<h3 class="box-title">
|
|
<i class="fa fa-bar-chart"></i> Résumé des Livraisons
|
|
<span id="storeNameDisplay" style="color: #764ba2; margin-left: 10px;"></span>
|
|
</h3>
|
|
</div>
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="stat-card">
|
|
<i class="fa fa-check-circle" style="font-size: 40px; color: #2196f3;"></i>
|
|
<div class="stat-number" id="totalValidations">0</div>
|
|
<div class="stat-label">Total Livraisons</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="stat-card">
|
|
<i class="fa fa-calendar" style="font-size: 40px; color: #2196f3;"></i>
|
|
<div class="stat-number" id="todayValidations">0</div>
|
|
<div class="stat-label">Livraisons Aujourd'hui</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="stat-card">
|
|
<i class="fa fa-motorcycle" style="font-size: 40px; color: #2196f3;"></i>
|
|
<div class="stat-number" id="monthValidations">0</div>
|
|
<div class="stat-label">Livraisons ce Mois</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filtres -->
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="filter-section">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<label for="filterStartDate">Date de début</label>
|
|
<input type="date" id="filterStartDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="filterEndDate">Date de fin</label>
|
|
<input type="date" id="filterEndDate" class="form-control">
|
|
</div>
|
|
<!-- ✅ FILTRE PAR MAGASIN -->
|
|
<div class="col-md-3">
|
|
<label for="filterStore">Magasin</label>
|
|
<select id="filterStore" class="form-control">
|
|
<option value="">Tous les magasins</option>
|
|
<?php if (isset($stores) && is_array($stores)): ?>
|
|
<?php foreach ($stores as $store): ?>
|
|
<option value="<?= $store['id'] ?>"><?= $store['name'] ?></option>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<label> </label><br>
|
|
<button id="btnFilter" class="btn btn-primary">
|
|
<i class="fa fa-filter"></i> Filtrer
|
|
</button>
|
|
<button id="btnReset" class="btn btn-warning">
|
|
<i class="fa fa-refresh"></i> Réinitialiser
|
|
</button>
|
|
<button id="btnExport" class="btn btn-success">
|
|
<i class="fa fa-file-excel-o"></i> Exporter
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tableau historique -->
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="box">
|
|
<div class="box-header with-border">
|
|
<h3 class="box-title">
|
|
<i class="fa fa-history"></i> Historique des Livraisons
|
|
</h3>
|
|
</div>
|
|
<div class="box-body">
|
|
<div class="table-responsive">
|
|
<table id="historyTable" class="table table-bordered table-striped table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Image</th>
|
|
<th>N° Facture</th>
|
|
<th>Désignation</th>
|
|
<th>UGS</th>
|
|
<th>Marque</th>
|
|
<th>Client</th>
|
|
<th>Magasin</th>
|
|
<th>Agent Sécurité</th>
|
|
<th>Date Validation</th>
|
|
<th>Statut</th>
|
|
<th>Quantité</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Les données seront chargées par DataTables -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<!-- Modal Détails -->
|
|
<div class="modal fade" id="detailsModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white;">
|
|
<button type="button" class="close" data-dismiss="modal" style="color: white;">×</button>
|
|
<h4 class="modal-title">
|
|
<i class="fa fa-info-circle"></i> Détails de la Validation
|
|
</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-4 text-center">
|
|
<img id="detailImage" class="img-responsive img-thumbnail" src="" alt="Image moto" style="max-height: 250px;">
|
|
</div>
|
|
<div class="col-md-8">
|
|
<h4 style="border-bottom: 2px solid #667eea; padding-bottom: 10px; margin-bottom: 20px;">
|
|
<i class="fa fa-motorcycle"></i> Informations Produit
|
|
</h4>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>N° Facture:</strong></div>
|
|
<div class="col-xs-6"><span id="detailBillNo"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Désignation:</strong></div>
|
|
<div class="col-xs-6"><span id="detailDesignation"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>UGS:</strong></div>
|
|
<div class="col-xs-6"><span id="detailUGS"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Marque:</strong></div>
|
|
<div class="col-xs-6"><span id="detailMarque"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>N° de Série:</strong></div>
|
|
<div class="col-xs-6"><span id="detailSerie"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Magasin:</strong></div>
|
|
<div class="col-xs-6"><span id="detailStore"></span></div>
|
|
</div>
|
|
|
|
<h4 style="border-bottom: 2px solid #667eea; padding-bottom: 10px; margin: 20px 0;">
|
|
<i class="fa fa-user"></i> Informations Client
|
|
</h4>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Nom:</strong></div>
|
|
<div class="col-xs-6"><span id="detailClientName"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Téléphone:</strong></div>
|
|
<div class="col-xs-6"><span id="detailClientPhone"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Adresse:</strong></div>
|
|
<div class="col-xs-6"><span id="detailClientAddress"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>CIN:</strong></div>
|
|
<div class="col-xs-6"><span id="detailClientCIN"></span></div>
|
|
</div>
|
|
|
|
<h4 style="border-bottom: 2px solid #667eea; padding-bottom: 10px; margin: 20px 0;">
|
|
<i class="fa fa-shield"></i> Informations Validation
|
|
</h4>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Agent Sécurité:</strong></div>
|
|
<div class="col-xs-6"><span id="detailAgent" class="agent-name"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Date Validation:</strong></div>
|
|
<div class="col-xs-6"><span id="detailDateValidation"></span></div>
|
|
</div>
|
|
<div class="row" style="margin-bottom: 15px;">
|
|
<div class="col-xs-6"><strong>Statut:</strong></div>
|
|
<div class="col-xs-6"><span id="detailStatut"></span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">
|
|
<i class="fa fa-times"></i> Fermer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
|
<script>
|
|
$(function() {
|
|
$("#securiteNav").addClass('active');
|
|
|
|
// Configuration DataTable en français
|
|
$.extend(true, $.fn.dataTable.defaults, {
|
|
language: {
|
|
sProcessing: "Traitement en cours...",
|
|
sSearch: "Rechercher :",
|
|
sLengthMenu: "Afficher _MENU_ éléments",
|
|
sInfo: "Affichage de _START_ à _END_ sur _TOTAL_ éléments",
|
|
sInfoEmpty: "Aucun élément à afficher",
|
|
sInfoFiltered: "(filtré de _MAX_ éléments au total)",
|
|
sLoadingRecords: "Chargement en cours...",
|
|
sZeroRecords: "Aucune validation trouvée",
|
|
sEmptyTable: "Aucune donnée disponible",
|
|
oPaginate: {
|
|
sFirst: "Premier",
|
|
sPrevious: "Précédent",
|
|
sNext: "Suivant",
|
|
sLast: "Dernier"
|
|
}
|
|
}
|
|
});
|
|
|
|
// ✅ INITIALISER LES DATES À AUJOURD'HUI PAR DÉFAUT
|
|
var today = new Date().toISOString().split('T')[0];
|
|
$('#filterStartDate').val(today);
|
|
$('#filterEndDate').val(today);
|
|
|
|
// ✅ CHARGER LES STATISTIQUES DU MOIS AU DÉMARRAGE
|
|
loadStatisticsForCurrentMonth();
|
|
|
|
// ✅ INITIALISATION DATATABLE
|
|
var historyTable = $('#historyTable').DataTable({
|
|
ajax: {
|
|
url: '<?= base_url('reports/detail/fetchSecuritePerformances') ?>',
|
|
type: 'GET',
|
|
data: function(d) {
|
|
d.startDate = $('#filterStartDate').val();
|
|
d.endDate = $('#filterEndDate').val();
|
|
d.store_id = $('#filterStore').val();
|
|
|
|
console.log('📤 Filtres envoyés:', {
|
|
startDate: d.startDate,
|
|
endDate: d.endDate,
|
|
store_id: d.store_id
|
|
});
|
|
},
|
|
dataSrc: function(json) {
|
|
console.log('📥 Données reçues:', json.data.length, 'lignes');
|
|
return json.data;
|
|
},
|
|
error: function(xhr, error, code) {
|
|
console.error('❌ Erreur DataTables:', error);
|
|
alert('Erreur lors du chargement des données');
|
|
}
|
|
},
|
|
columns: [
|
|
{ data: 0, orderable: false, render: function(data) {
|
|
return '<img src="' + data + '" class="moto-image" alt="Moto">';
|
|
}},
|
|
{ data: 1 },
|
|
{ data: 2 },
|
|
{ data: 3 },
|
|
{ data: 4 },
|
|
{ data: 5 },
|
|
{ data: 7, render: function(data) {
|
|
return '<span class="badge badge-info">' + data + '</span>';
|
|
}},
|
|
{ data: 6, render: function(data) {
|
|
return '<span class="agent-name">' + data + '</span>';
|
|
}},
|
|
{ data: 8, render: function(data) {
|
|
return '<span class="validation-date">' + data + '</span>';
|
|
}},
|
|
{ data: 9, orderable: false },
|
|
{ data: 10, orderable: true, className: 'text-center', render: function(data) {
|
|
return '<span class="badge badge-primary">' + data + '</span>';
|
|
}}
|
|
],
|
|
order: [[8, 'desc']],
|
|
pageLength: 10,
|
|
lengthMenu: [[5, 10, 25, 50, -1], [5, 10, 25, 50, "Tout"]]
|
|
});
|
|
|
|
// ✅ BOUTON FILTRER - RECHARGE TABLEAU + STATISTIQUES
|
|
$('#btnFilter').on('click', function() {
|
|
console.log('🔍 Bouton Filtrer cliqué');
|
|
|
|
var startDate = $('#filterStartDate').val();
|
|
var endDate = $('#filterEndDate').val();
|
|
var storeId = $('#filterStore').val();
|
|
|
|
console.log('Dates:', startDate, 'à', endDate);
|
|
console.log('Store ID:', storeId || 'Tous');
|
|
|
|
historyTable.ajax.reload();
|
|
|
|
// ✅ RECHARGER LES STATISTIQUES SELON LA PÉRIODE ET LE MAGASIN FILTRÉS
|
|
loadStatisticsForFilteredPeriod(startDate, endDate, storeId);
|
|
});
|
|
|
|
// ✅ BOUTON RÉINITIALISER
|
|
$('#btnReset').on('click', function() {
|
|
console.log('🔄 Réinitialisation des filtres');
|
|
|
|
var today = new Date().toISOString().split('T')[0];
|
|
$('#filterStartDate').val(today);
|
|
$('#filterEndDate').val(today);
|
|
$('#filterStore').val('');
|
|
$('#storeNameDisplay').text('');
|
|
|
|
historyTable.ajax.reload();
|
|
loadStatisticsForCurrentMonth();
|
|
});
|
|
|
|
// ✅ CHANGEMENT DE MAGASIN - METTRE À JOUR LES STATS
|
|
$('#filterStore').on('change', function() {
|
|
var storeId = $(this).val();
|
|
var storeName = $(this).find('option:selected').text();
|
|
var startDate = $('#filterStartDate').val();
|
|
var endDate = $('#filterEndDate').val();
|
|
|
|
console.log('🏪 Magasin changé:', storeName);
|
|
|
|
// Afficher le nom du magasin dans le titre
|
|
if (storeId) {
|
|
$('#storeNameDisplay').text('- ' + storeName);
|
|
} else {
|
|
$('#storeNameDisplay').text('');
|
|
}
|
|
|
|
// Recharger automatiquement le tableau et les stats
|
|
historyTable.ajax.reload();
|
|
|
|
if (startDate && endDate) {
|
|
loadStatisticsForFilteredPeriod(startDate, endDate, storeId);
|
|
} else {
|
|
loadStatisticsForCurrentMonth();
|
|
}
|
|
});
|
|
|
|
// ✅ FONCTION : CHARGER LES STATISTIQUES DU MOIS EN COURS
|
|
function loadStatisticsForCurrentMonth() {
|
|
console.log('📊 Chargement des statistiques du mois en cours...');
|
|
|
|
var now = new Date();
|
|
var firstDay = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
var lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
|
|
|
var startDate = firstDay.toISOString().split('T')[0];
|
|
var endDate = lastDay.toISOString().split('T')[0];
|
|
|
|
loadStatisticsForFilteredPeriod(startDate, endDate, '');
|
|
}
|
|
|
|
// ✅ FONCTION : CHARGER LES STATISTIQUES POUR UNE PÉRIODE ET UN MAGASIN DONNÉS
|
|
function loadStatisticsForFilteredPeriod(startDate, endDate, storeId) {
|
|
console.log('📊 Chargement des statistiques pour:', startDate, 'au', endDate, 'Store ID:', storeId || 'TOUS');
|
|
|
|
$.ajax({
|
|
url: '<?= base_url('reports/detail/fetchSecuritePerformances') ?>',
|
|
type: 'GET',
|
|
data: {
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
store_id: storeId
|
|
},
|
|
success: function(response) {
|
|
console.log('✅ Statistiques chargées:', response.data.length, 'lignes');
|
|
calculateStatistics(response.data, startDate, endDate, storeId);
|
|
},
|
|
error: function(xhr, error) {
|
|
console.error('❌ Erreur chargement statistiques:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// ✅ FONCTION POUR CALCULER LES STATISTIQUES (AVEC FILTRAGE PAR MAGASIN)
|
|
function calculateStatistics(data, filterStartDate, filterEndDate, filterStoreId) {
|
|
var today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
|
|
var todayCount = 0;
|
|
var monthCount = 0;
|
|
|
|
var filteredMonth = null;
|
|
var filteredYear = null;
|
|
|
|
if (filterStartDate && filterEndDate) {
|
|
var startDateObj = new Date(filterStartDate);
|
|
var endDateObj = new Date(filterEndDate);
|
|
|
|
if (startDateObj.getMonth() === endDateObj.getMonth() &&
|
|
startDateObj.getFullYear() === endDateObj.getFullYear()) {
|
|
filteredMonth = startDateObj.getMonth();
|
|
filteredYear = startDateObj.getFullYear();
|
|
}
|
|
}
|
|
|
|
$.each(data, function(i, item) {
|
|
var itemDateStr = item[8]; // Date de validation
|
|
|
|
if (itemDateStr && itemDateStr !== 'N/A') {
|
|
try {
|
|
var date;
|
|
|
|
if (itemDateStr.includes('/')) {
|
|
var parts = itemDateStr.split(' ')[0].split('/');
|
|
date = new Date(parts[2], parts[1] - 1, parts[0]);
|
|
} else {
|
|
date = new Date(itemDateStr);
|
|
}
|
|
|
|
if (!isNaN(date.getTime())) {
|
|
date.setHours(0, 0, 0, 0);
|
|
|
|
// Compter aujourd'hui
|
|
if (date.getTime() === today.getTime()) {
|
|
todayCount++;
|
|
}
|
|
|
|
// Compter le mois filtré (ou mois en cours)
|
|
if (filteredMonth !== null) {
|
|
if (date.getMonth() === filteredMonth && date.getFullYear() === filteredYear) {
|
|
monthCount++;
|
|
}
|
|
} else {
|
|
if (date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear()) {
|
|
monthCount++;
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.warn('Date invalide:', itemDateStr, e);
|
|
}
|
|
}
|
|
});
|
|
|
|
// ✅ METTRE À JOUR LES COMPTEURS
|
|
$('#totalValidations').text(monthCount);
|
|
$('#todayValidations').text(todayCount);
|
|
$('#monthValidations').text(monthCount);
|
|
|
|
console.log('📈 Statistiques:', {
|
|
store_id: filterStoreId || 'TOUS',
|
|
total: monthCount,
|
|
aujourd_hui: todayCount,
|
|
ce_mois: monthCount,
|
|
periode_filtree: filterStartDate + ' au ' + filterEndDate
|
|
});
|
|
}
|
|
|
|
// ✅ BOUTON EXPORT EXCEL
|
|
$('#btnExport').on('click', function() {
|
|
var wb = XLSX.utils.book_new();
|
|
var data = [];
|
|
|
|
data.push([
|
|
'N° Facture',
|
|
'Désignation',
|
|
'UGS',
|
|
'Marque',
|
|
'Client',
|
|
'Magasin',
|
|
'Agent Sécurité',
|
|
'Date Validation',
|
|
'Statut',
|
|
'Quantité'
|
|
]);
|
|
|
|
historyTable.rows({ search: 'applied' }).every(function() {
|
|
var rowData = this.data();
|
|
data.push([
|
|
rowData[1],
|
|
rowData[2],
|
|
rowData[3],
|
|
rowData[4],
|
|
rowData[5],
|
|
rowData[7],
|
|
rowData[6],
|
|
rowData[8],
|
|
'VALIDÉE',
|
|
rowData[10]
|
|
]);
|
|
});
|
|
|
|
var ws = XLSX.utils.aoa_to_sheet(data);
|
|
|
|
ws['!cols'] = [
|
|
{ wch: 15 }, { wch: 30 }, { wch: 15 }, { wch: 20 }, { wch: 25 },
|
|
{ wch: 20 }, { wch: 25 }, { wch: 20 }, { wch: 12 }, { wch: 10 }
|
|
];
|
|
|
|
XLSX.utils.book_append_sheet(wb, ws, "Historique");
|
|
|
|
var today = new Date().toISOString().split('T')[0];
|
|
var filename = 'historique_livraisons_' + today + '.xlsx';
|
|
|
|
XLSX.writeFile(wb, filename);
|
|
|
|
console.log('✅ Export Excel réalisé:', filename);
|
|
});
|
|
|
|
});
|
|
|
|
// ✅ FONCTION POUR AFFICHER LES DÉTAILS
|
|
function viewDetails(id) {
|
|
$.get('<?= base_url('reports/detail/getSecuriteValidationDetails') ?>/' + id, function(data) {
|
|
$('#detailImage').attr('src', data[0]);
|
|
$('#detailBillNo').text(data[1]);
|
|
$('#detailDesignation').text(data[2]);
|
|
$('#detailUGS').text(data[3]);
|
|
$('#detailMarque').text(data[4]);
|
|
$('#detailSerie').text(data[3]);
|
|
$('#detailStore').text(data[7]);
|
|
$('#detailClientName').text(data[5]);
|
|
$('#detailClientPhone').text(data[12]);
|
|
$('#detailClientAddress').text(data[13]);
|
|
$('#detailClientCIN').text(data[14]);
|
|
$('#detailAgent').text(data[6]);
|
|
$('#detailDateValidation').text(formatDate(data[8]));
|
|
$('#detailStatut').html(data[9]);
|
|
|
|
var additionalInfo = '';
|
|
if (data[15] && data[15] !== 'N/A') {
|
|
additionalInfo += '<div class="row" style="margin-bottom: 15px;">';
|
|
additionalInfo += '<div class="col-xs-6"><strong>N° de Moteur:</strong></div>';
|
|
additionalInfo += '<div class="col-xs-6"><span>' + data[15] + '</span></div>';
|
|
additionalInfo += '</div>';
|
|
}
|
|
if (data[16] && data[16] !== 'N/A') {
|
|
additionalInfo += '<div class="row" style="margin-bottom: 15px;">';
|
|
additionalInfo += '<div class="col-xs-6"><strong>N° de Châssis:</strong></div>';
|
|
additionalInfo += '<div class="col-xs-6"><span>' + data[16] + '</span></div>';
|
|
additionalInfo += '</div>';
|
|
}
|
|
|
|
if (additionalInfo) {
|
|
$('#detailSerie').closest('.row').after(additionalInfo);
|
|
}
|
|
|
|
$('#detailsModal').modal('show');
|
|
}, 'json');
|
|
}
|
|
|
|
// ✅ FONCTION POUR FORMATER LA DATE
|
|
function formatDate(dateString) {
|
|
if (!dateString || dateString === 'N/A') return 'N/A';
|
|
|
|
try {
|
|
var date;
|
|
|
|
if (dateString.includes('/')) {
|
|
var parts = dateString.split(' ');
|
|
var dateParts = parts[0].split('/');
|
|
var timeParts = parts[1] ? parts[1].split(':') : ['00', '00'];
|
|
date = new Date(dateParts[2], dateParts[1] - 1, dateParts[0], timeParts[0], timeParts[1]);
|
|
} else {
|
|
date = new Date(dateString);
|
|
}
|
|
|
|
if (isNaN(date.getTime())) {
|
|
return dateString;
|
|
}
|
|
|
|
var options = {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
};
|
|
return date.toLocaleDateString('fr-FR', options);
|
|
} catch (e) {
|
|
console.warn('Erreur formatage date:', dateString, e);
|
|
return dateString;
|
|
}
|
|
}
|
|
</script>
|