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.
1209 lines
50 KiB
1209 lines
50 KiB
<style>
|
|
.card {
|
|
border-radius: 12px;
|
|
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.table {
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
}
|
|
.mecanicien {
|
|
margin-left: 8px;
|
|
margin-right: 8px;
|
|
}
|
|
|
|
th {
|
|
text-align: center;
|
|
background-color: #343a40 !important;
|
|
color: white;
|
|
}
|
|
|
|
tbody tr:hover {
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.btn-primary {
|
|
border-radius: 8px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.bg-primary {
|
|
background-color: #007bff !important;
|
|
}
|
|
|
|
.bg-success {
|
|
background-color: #28a745 !important;
|
|
}
|
|
|
|
.bg-warning {
|
|
background-color: #ffc107 !important;
|
|
}
|
|
</style>
|
|
|
|
<div class="content-wrapper">
|
|
<!-- Content Header (Page header) -->
|
|
<section class="content-header">
|
|
<h1>
|
|
Tableau de bord
|
|
<small>Panneau de configuration</small>
|
|
</h1>
|
|
<ol class="breadcrumb">
|
|
<li><a href="#"><i class="fa fa-dashboard"></i> Accueil</a></li>
|
|
<li class="active">Tableau de bord</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<!-- Main content -->
|
|
<section class="content">
|
|
<!-- Small boxes (Stat box) -->
|
|
<?php if ($is_admin == true): ?>
|
|
|
|
<div class="row">
|
|
<div class="col-lg-2 col-xs-4">
|
|
<!-- small box -->
|
|
<div class="small-box bg-aqua">
|
|
<div class="inner">
|
|
<h3><?php echo $total_products ?></h3>
|
|
|
|
<p>Produit</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="ion ion-bag"></i>
|
|
</div>
|
|
<a href="<?php echo base_url('products/') ?>" class="small-box-footer">Plus d'information<i class="fa fa-arrow-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
<!-- ./col -->
|
|
|
|
<div class="col-lg-2 col-xs-4">
|
|
<!-- small box -->
|
|
<div class="small-box bg-green">
|
|
<div class="inner">
|
|
<h3><?php echo $total_paid_orders ?></h3>
|
|
|
|
<p>Commande payée</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="ion ion-stats-bars"></i>
|
|
</div>
|
|
<a href="<?php echo base_url('orders/') ?>" class="small-box-footer">Plus d'information <i class="fa fa-arrow-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
<!-- ./col -->
|
|
<div class="col-lg-2 col-xs-4">
|
|
<!-- small box -->
|
|
<div class="small-box bg-yellow">
|
|
<div class="inner">
|
|
<h3><?php echo $total_users; ?></h3>
|
|
|
|
<p>Utilisateur</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="ion ion-android-people"></i>
|
|
</div>
|
|
<a href="<?php echo base_url('users/') ?>" class="small-box-footer">Plus d'information <i class="fa fa-arrow-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
<!-- ./col -->
|
|
<div class="col-lg-2 col-xs-4">
|
|
<!-- small box -->
|
|
<div class="small-box bg-red">
|
|
<div class="inner">
|
|
<h3><?php echo $total_stores ?></h3>
|
|
|
|
<p>Point de vente</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="ion ion-android-home"></i>
|
|
</div>
|
|
<a href="<?php echo base_url('stores/') ?>" class="small-box-footer">Plus d'information <i class="fa fa-arrow-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
<!-- ./col -->
|
|
|
|
<!-- ./col -->
|
|
<div class="col-lg-4 col-xs-4">
|
|
<!-- small box -->
|
|
<div class="small-box bg-primary">
|
|
<div class="inner" style="color:white;">
|
|
<h3><?php echo count($count_id) ?></h3>
|
|
|
|
<p>Statistique des Commercials</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="ion-stats-bars"></i>
|
|
</div>
|
|
<a href="<?php echo base_url('statistic/') ?>" class="small-box-footer">Plus d'information <i class="fa fa-arrow-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
<!-- End of row -->
|
|
</div>
|
|
<div class="row">
|
|
<!-- total en caisse -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale FLUX</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa-credit-card"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- total mvola -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total_mvola, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale MVOLA</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa-mobile-alt"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Total en espece -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total_espece, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale en espece</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa fa-usd"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Total en virement bancaire -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total_virement_bancaire, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale en banque</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa-credit-card-alt"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- /.row -->
|
|
<div class="row" style="padding: 15px;">
|
|
<div class="col-lg-6 col-xs-12" style="background-color: white; box-shadow: inset 1px 1px 3px #00000052; padding: 20px; text-align: center;">
|
|
<div class="box-header">
|
|
<h3 class="box-title">Statistique des ventes par magasin</h3>
|
|
</div>
|
|
<div class="box-body" style="display: flex; justify-content: center; align-items: center; height: 300px;">
|
|
<canvas id="storeChart" style="max-width: 100%; height: 280px;"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="col-lg-6 col-xs-12" style="background-color: white; box-shadow: inset 1px 1px 3px #00000052; padding: 20px; text-align: center;">
|
|
<div>
|
|
<div class="box-header">
|
|
<h3 class="box-title">Liste des marques les plus vendues</h3>
|
|
</div>
|
|
<div class="box-body" style="display: flex; justify-content: center; align-items: center; height: 300px;">
|
|
<canvas id="MotosChart" style="max-width: 100%; height: 280px;"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<!-- performance content wraper: <div class="content-wrapper"> -->
|
|
<section class="content-header">
|
|
<h1> Rapports des performances</h1>
|
|
<ol class="breadcrumb">
|
|
<li><a href="#"><i class="fa fa-home"></i> Accueil</a></li>
|
|
<li class="active" onclick="window.history.back()" style="cursor: pointer;"> Rapports</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<section class="content">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body">
|
|
<!-- Product Details -->
|
|
<div class="row mt-4">
|
|
<div class="col-md-12 col-lg-12">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-success text-white">
|
|
<h3 class="card-title m-0"> performances des commercials</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row g-3 align-items-center mb-4" style="margin: 5px 0 5px 5px;">
|
|
<div class="col-md-3">
|
|
<label for="startDate" class="form-label">Date de début</label>
|
|
<input type="date" id="startDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="endDate" class="form-label">Date de fin</label>
|
|
<input type="date" id="endDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="pvente" class="form-label">Points de ventes</label>
|
|
<select name="" id="pvente" class="form-control">
|
|
<option value="TOUS">TOUS</option>
|
|
<?php
|
|
foreach ($stores as $value) {
|
|
?>
|
|
<option value="<?= $value['name']; ?>"><?= $value['name']; ?>
|
|
</option>
|
|
<?php
|
|
}
|
|
|
|
?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3 d-flex align-items-end">
|
|
<br>
|
|
<button id="filteredB1" class="btn btn-primary w-100">Filtrer
|
|
🔍</button>
|
|
<button id="ExportBTN1" class="btn btn-success w-100">Exporter
|
|
📤</button>
|
|
</div>
|
|
</div>
|
|
<table id="commperformance" class="table table-hover table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Nom et prénom</th>
|
|
<th>Email</th>
|
|
<th>Motos vendue</th>
|
|
<th>Date de vente</th><!-- return 2025-04-18 -->
|
|
<th>Prix d'achat</th>
|
|
<th>Prix de vente</th>
|
|
<th>Point de ventes</th>
|
|
<th>Bénefices</th>
|
|
</tr>
|
|
</thead>
|
|
<tfoot>
|
|
<tr>
|
|
<th colspan="5" style="text-align:right">Total:</th>
|
|
<th></th> <!-- total Prix de vente -->
|
|
<th></th>
|
|
<th></th> <!-- total Bénéfices -->
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body">
|
|
<!-- Product Details -->
|
|
<div class="row mt-4">
|
|
<div class="col-md-12 col-lg-12">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-success text-white">
|
|
<h3 class="card-title m-0">📈 performances des Mécanicien</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row g-3 align-items-center mb-4" style="margin: 5px 0 5px 5px;">
|
|
<div class="col-md-3">
|
|
<label for="startDate2" class="form-label">Date de début</label>
|
|
<input type="date" id="startDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="endDate2" class="form-label">Date de fin</label>
|
|
<input type="date" id="endDate" class="form-control">
|
|
</div>
|
|
<?php $session = session();
|
|
$users = $session->get('user');
|
|
if ($users["group_name"] === "Direction") :
|
|
|
|
?>
|
|
<div class="col-md-3">
|
|
<label for="pvente" class="form-label">Points de ventes</label>
|
|
<select name="" id="pvente2" class="form-control">
|
|
<option value="TOUS">TOUS</option>
|
|
<?php
|
|
foreach ($stores as $value) {
|
|
?>
|
|
<option value="<?= $value['name']; ?>"><?= $value['name']; ?>
|
|
</option>
|
|
<?php
|
|
}
|
|
|
|
?>
|
|
</select>
|
|
</div>
|
|
<?php endif; ?>
|
|
<div class="col-md-3 d-flex align-items-end">
|
|
<br>
|
|
<button id="filteredB2" class="btn btn-primary w-100">Filtrer
|
|
🔍</button>
|
|
<button id="ExportBTN2" class="btn btn-success w-100">Exporter
|
|
📤</button>
|
|
</div>
|
|
</div>
|
|
<table id="mecperformance" class="table table-hover table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Mécaniciens</th>
|
|
<th >Motos</th>
|
|
<th >Désignation</th>
|
|
<th >Numéro de série</th>
|
|
<th >Début de la réparation</th>
|
|
<th >Fin de la réparation</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
|
<script>
|
|
var manageTable;
|
|
|
|
$(document).ready(function () {
|
|
|
|
// Initialize the datatable
|
|
$.extend(true, $.fn.dataTable.defaults, {
|
|
language: {
|
|
sProcessing: "Traitement en cours...",
|
|
sSearch: "Rechercher :",
|
|
sLengthMenu: "Afficher _MENU_ éléments",
|
|
sInfo: "Affichage de l'élement _START_ à _END_ sur _TOTAL_ éléments",
|
|
sInfoEmpty: "Affichage de l'élement 0 à 0 sur 0 élément",
|
|
sInfoFiltered: "(filtré de _MAX_ éléments au total)",
|
|
sLoadingRecords: "Chargement en cours...",
|
|
sZeroRecords: "Aucun élément à afficher",
|
|
sEmptyTable: "Aucune donnée disponible dans le tableau",
|
|
oPaginate: {
|
|
sFirst: "Premier",
|
|
sPrevious: "Précédent",
|
|
sNext: "Suivant",
|
|
sLast: "Dernier"
|
|
},
|
|
oAria: {
|
|
sSortAscending: ": activer pour trier la colonne par ordre croissant",
|
|
sSortDescending: ": activer pour trier la colonne par ordre décroissant"
|
|
}
|
|
}
|
|
});
|
|
manageTable = $('#commperformance').DataTable({
|
|
'ajax': 'reports/detail/fetchPerformances',
|
|
'order': [],
|
|
'pageLength': 5,
|
|
'lengthMenu': [
|
|
[5, 10, 25, 50, -1],
|
|
[5, 10, 25, 50, "All"]
|
|
],
|
|
"columnDefs": [{
|
|
"targets": 3, // Ensure date column is not searchable (we handle it manually)
|
|
"searchable": false
|
|
}],
|
|
"footerCallback": function (row, data, start, end, display) {
|
|
const api = this.api();
|
|
|
|
// Helper function to parse string to float
|
|
const parseNumber = function (i) {
|
|
return typeof i === 'string' ?
|
|
parseFloat(i.replace(/[^\d.-]/g, '')) : // remove currency symbols, commas
|
|
typeof i === 'number' ?
|
|
i : 0;
|
|
};
|
|
|
|
// Calculate total for Prix de vente (column 5)
|
|
const totalPrixVente = api
|
|
.column(5, { page: 'current' })
|
|
.data()
|
|
.reduce((a, b) => parseNumber(a) + parseNumber(b), 0);
|
|
|
|
const totalPrixVenteFormate = totalPrixVente.toLocaleString('fr-FR');
|
|
|
|
|
|
// Calculate total for Bénefices (column 7)
|
|
const totalBenefices = api
|
|
.column(7, { page: 'current' })
|
|
.data()
|
|
.reduce((a, b) => parseNumber(a) + parseNumber(b), 0);
|
|
const totalPrixBeneficeFormate = totalBenefices.toLocaleString('fr-FR');
|
|
|
|
// Update footer
|
|
$(api.column(5).footer()).html(totalPrixVenteFormate.toFixe);
|
|
$(api.column(7).footer()).html(totalPrixBeneficeFormate);
|
|
}
|
|
});
|
|
|
|
$('#filteredB1').on('click', function () {
|
|
const startDate = $('#startDate').val();
|
|
const endDate = $('#endDate').val();
|
|
const pvente = $('#pvente').val();
|
|
|
|
// Get all original data (you may need to fetch from server or already loaded)
|
|
manageTable.ajax.url('reports/detail/fetchPerformances').load(function () {
|
|
const filteredData = [];
|
|
|
|
manageTable.rows().every(function () {
|
|
const data = this.data();
|
|
const saleDate = data[3].split(' ')[0]; // extract YYYY-MM-DD from date
|
|
const store = data[6];
|
|
|
|
// Filter logic
|
|
const dateMatch = (!startDate && !endDate) ||
|
|
(startDate && endDate && saleDate >= startDate && saleDate <= endDate) ||
|
|
(startDate && !endDate && saleDate >= startDate) ||
|
|
(!startDate && endDate && saleDate <= endDate);
|
|
|
|
const storeMatch = (pvente === 'TOUS' || pvente === store);
|
|
|
|
if (dateMatch && storeMatch) {
|
|
filteredData.push(data);
|
|
}
|
|
});
|
|
|
|
// Clear and reload table with filtered data
|
|
manageTable.clear().rows.add(filteredData).draw();
|
|
});
|
|
});
|
|
|
|
manageTable = $('#mecperformance').DataTable({
|
|
'ajax': 'mecanicien/fetchMecanicienPerformances',
|
|
'order': [],
|
|
columnDefs: [
|
|
{
|
|
targets: "_all", // ou un index de colonne, ou un tableau d’index
|
|
className: "text-left" // ou "dt-left" si tu utilises les classes par défaut de DataTables
|
|
}
|
|
],
|
|
|
|
});
|
|
|
|
// Filtrage par dates
|
|
$('#filteredB1').on('click', function () {
|
|
const startDate = $('#startDate').val();
|
|
const endDate = $('#endDate').val();
|
|
|
|
manageTable.ajax.url('mecanicien/fetchMecanicienPerformances').load(function () {
|
|
const filteredData = [];
|
|
|
|
manageTable.rows().every(function () {
|
|
const data = this.data();
|
|
const repairDate = data[2].split(' ')[0]; // Début réparation
|
|
|
|
const isValid =
|
|
(!startDate && !endDate) ||
|
|
(startDate && endDate && repairDate >= startDate && repairDate <= endDate) ||
|
|
(startDate && !endDate && repairDate >= startDate) ||
|
|
(!startDate && endDate && repairDate <= endDate);
|
|
|
|
if (isValid) {
|
|
filteredData.push(data);
|
|
}
|
|
});
|
|
|
|
manageTable.clear().rows.add(filteredData).draw();
|
|
});
|
|
});
|
|
});
|
|
|
|
document.getElementById('ExportBTN1').addEventListener('click', function () {
|
|
// Select your table
|
|
var table = document.getElementById('commperformance');
|
|
|
|
// Convert it to a workbook
|
|
var wb = XLSX.utils.table_to_book(table, {
|
|
sheet: "Feuille1"
|
|
});
|
|
|
|
// Export it
|
|
XLSX.writeFile(wb, 'export-commercial-performance.xlsx');
|
|
});
|
|
// Export en Excel mecanicien
|
|
$('#ExportBTN1').on('click', function () {
|
|
const table = document.getElementById('mecperformance');
|
|
const wb = XLSX.utils.table_to_book(table, { sheet: "Feuille1" });
|
|
XLSX.writeFile(wb, 'export-performance-mecanicien.xlsx');
|
|
});
|
|
</script>
|
|
|
|
<?php endif; ?>
|
|
<?php if ($isCommercial === true || $isChef === true) : ?>
|
|
<!-- <div class="content-wrapper"> -->
|
|
<!-- <h5>Votre statistique de vente</h5> -->
|
|
<!-- performance content wraper: <div class="content-wrapper"> -->
|
|
<section class="content-header">
|
|
<h1> Rapports des performances</h1>
|
|
<ol class="breadcrumb">
|
|
<li><a href="#"><i class="fa fa-home"></i> Accueil</a></li>
|
|
<li class="active" onclick="window.history.back()" style="cursor: pointer;"> Rapports</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<section class="content">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body">
|
|
<!-- Product Details -->
|
|
<div class="row mt-4">
|
|
<div class="col-md-12 col-lg-12">
|
|
<div class="card shadow-sm border-0">
|
|
|
|
<div class="card-body">
|
|
<div class="row g-3 align-items-center mb-4" style="margin: 5px 0 5px 5px;">
|
|
<div class="col-md-3">
|
|
<label for="startDate" class="form-label">Date de début</label>
|
|
<input type="date" id="startDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="endDate" class="form-label">Date de fin</label>
|
|
<input type="date" id="endDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3 d-flex align-items-end">
|
|
<br>
|
|
<button id="filteredB1" class="btn btn-primary w-100">Filtrer
|
|
🔍</button>
|
|
<button id="ExportBTN1" class="btn btn-success w-100">Exporter
|
|
📤</button>
|
|
</div>
|
|
</div>
|
|
<table id="commperformance" class="table table-hover table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Nom et prénom</th>
|
|
<th>Motos vendues</th>
|
|
<th>Date de vente</th>
|
|
<th>Prix de vente</th>
|
|
</tr>
|
|
</thead>
|
|
<tfoot>
|
|
<tr>
|
|
<th colspan="3" style="text-align:right">Total:</th>
|
|
<th></th>
|
|
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<div style="width: 80%; margin: auto;">
|
|
<canvas id="salesChart"></canvas>
|
|
</div>
|
|
<!-- /.content -->
|
|
</div>
|
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
|
<script>
|
|
var manageTable;
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
|
// Initialize the datatable
|
|
manageTable = $('#commperformance').DataTable({
|
|
'ajax': 'reports/detail/fetchPerformances',
|
|
'order': [],
|
|
'pageLength': 5,
|
|
'lengthMenu': [
|
|
[5, 10, 25, 50, -1],
|
|
[5, 10, 25, 50, "All"]
|
|
],
|
|
"columnDefs": [{
|
|
"targets": 3, // Ensure date column is not searchable (we handle it manually)
|
|
"searchable": true
|
|
}],
|
|
"footerCallback": function (row, data, start, end, display) {
|
|
const api = this.api();
|
|
|
|
// Helper function to parse string to float
|
|
const parseNumber = function (i) {
|
|
return typeof i === 'string' ?
|
|
parseFloat(i.replace(/[^\d.-]/g, '')) : // remove currency symbols, commas
|
|
typeof i === 'number' ?
|
|
i : 0;
|
|
};
|
|
|
|
// Calculate total for Prix de vente (column 5)
|
|
const totalPrixVente = api
|
|
.column(3, { page: 'current' })
|
|
.data()
|
|
.reduce((a, b) => parseNumber(a) + parseNumber(b), 0);
|
|
|
|
const totalPrixVenteFormate = totalPrixVente.toLocaleString('fr-FR');
|
|
|
|
// Update footer
|
|
$(api.column(3).footer()).html(totalPrixVenteFormate);
|
|
}
|
|
});
|
|
|
|
$('#filteredB1').on('click', function () {
|
|
const startDate = $('#startDate').val();
|
|
const endDate = $('#endDate').val();
|
|
const pvente = $('#pvente').val();
|
|
|
|
// Get all original data (you may need to fetch from server or already loaded)
|
|
manageTable.ajax.url('reports/detail/fetchPerformances').load(function () {
|
|
const filteredData = [];
|
|
|
|
manageTable.rows().every(function () {
|
|
const data = this.data();
|
|
const saleDate = data[2].split(' ')[0];
|
|
|
|
// Filter logic
|
|
const dateMatch = (!startDate && !endDate) ||
|
|
(startDate && endDate && saleDate >= startDate && saleDate <= endDate) ||
|
|
(startDate && !endDate && saleDate >= startDate) ||
|
|
(!startDate && endDate && saleDate <= endDate);
|
|
|
|
|
|
if (dateMatch) {
|
|
filteredData.push(data);
|
|
}
|
|
});
|
|
|
|
// Clear and reload table with filtered data
|
|
manageTable.clear().rows.add(filteredData).draw();
|
|
});
|
|
});
|
|
});
|
|
|
|
document.getElementById('ExportBTN1').addEventListener('click', function () {
|
|
// Select your table
|
|
var table = document.getElementById('commperformance');
|
|
|
|
// Convert it to a workbook
|
|
var wb = XLSX.utils.table_to_book(table, {
|
|
sheet: "Feuille1"
|
|
});
|
|
|
|
// Export it
|
|
XLSX.writeFile(wb, 'export-commercial-performance.xlsx');
|
|
});
|
|
</script>
|
|
<!-- </div> -->
|
|
<?php endif; ?>
|
|
</section>
|
|
|
|
|
|
<?php if ($isCaissier === true): ?>
|
|
<!-- <div class="content-wrapper"> -->
|
|
<!-- <h5>Votre statistique de vente</h5> -->
|
|
<!-- performance content wraper: <div class="content-wrapper"> -->
|
|
<div class=" container-fluid row">
|
|
<!-- total en caisse -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale CAISSE</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa-credit-card"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- total mvola -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total_mvola, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale MVOLA</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa-mobile-alt"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Total en espece -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total_espece, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale en espece</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa fa-usd"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Total en virement bancaire -->
|
|
<div class="col-lg-3 col-xs-6">
|
|
<!-- small box -->
|
|
<div class="small-box" style="background-color: #A9A9A9;">
|
|
<div class="inner">
|
|
<h2><?php echo number_format($total_virement_bancaire, 0, '.', ' '); ?>Ar</h2>
|
|
<p>Totale en banque</p>
|
|
</div>
|
|
<div class="icon">
|
|
<i class="fa fa-credit-card-alt"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<section class="content-header">
|
|
<h1> Rapport de Performance du Caissier</h1>
|
|
<ol class="breadcrumb">
|
|
<li><a href="#"><i class="fa fa-home"></i> Accueil</a></li>
|
|
<li class="active" onclick="window.history.back()" style="cursor: pointer;"> Rapports</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<section class="content">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body">
|
|
<!-- Product Details -->
|
|
<div class="row mt-4">
|
|
<div class="col-md-12 col-lg-12">
|
|
<div class="card shadow-sm border-0">
|
|
|
|
<div class="card-body">
|
|
<div class="row g-3 align-items-center mb-4" style="margin: 5px 0 5px 5px;">
|
|
<div class="col-md-3">
|
|
<label for="startDate" class="form-label">Date de début</label>
|
|
<input type="date" id="startDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="endDate" class="form-label">Date de fin</label>
|
|
<input type="date" id="endDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3 d-flex align-items-end">
|
|
<br>
|
|
<button id="filteredB1" class="btn btn-primary w-100">Filtrer
|
|
🔍</button>
|
|
<button id="ExportBTN1" class="btn btn-success w-100">Exporter
|
|
📤</button>
|
|
</div>
|
|
</div>
|
|
<table id="caissierperf" class="table table-hover table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th id="me">MVOLA & Espèce</th>
|
|
<th id="bm">Banque & MVOLA</th>
|
|
<th id="be">Banque & Espèce</th>
|
|
<th id="mb">MVOLA & Banque</th>
|
|
<th id="mr">Montant total</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<div style="width: 80%; margin: auto;">
|
|
<canvas id="salesChart"></canvas>
|
|
</div>
|
|
<!-- /.content -->
|
|
|
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
|
<script>
|
|
var manageTable;
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
|
// Initialize the datatable
|
|
manageTable = $('#caissierperf').DataTable({
|
|
'ajax': 'recouvrement/fetchTotalRecouvrementData',
|
|
'order': [],
|
|
'pageLength': 5,
|
|
'lengthMenu': [
|
|
[5, 10, 25, 50, -1],
|
|
[5, 10, 25, 50, "All"]
|
|
],
|
|
"columnDefs": [{
|
|
"targets": "_all",
|
|
"className": "text-left"
|
|
}],
|
|
|
|
"footerCallback": function (row, data, start, end, display) {
|
|
const api = this.api();
|
|
|
|
// Helper function to parse string to float
|
|
const parseNumber = function (i) {
|
|
return typeof i === 'string' ?
|
|
parseFloat(i.replace(/[^\d.-]/g, '')) : // remove currency symbols, commas
|
|
typeof i === 'number' ?
|
|
i : 0;
|
|
};
|
|
|
|
}
|
|
});
|
|
|
|
$('#filteredB1').on('click', function () {
|
|
const startDate = $('#startDate').val();
|
|
const endDate = $('#endDate').val();
|
|
const pvente = $('#pvente').val(); // id de l'utilisateur ici
|
|
|
|
$.ajax({
|
|
url: '<?= base_url("recouvrement/fetchTotalRecouvrementData") ?>',
|
|
type: 'GET',
|
|
data: {
|
|
start_date: startDate,
|
|
end_date: endDate
|
|
},
|
|
dataType: 'json',
|
|
success: function (response) {
|
|
if (response) {
|
|
$('#mr').text(response.tr); // par exemple
|
|
$('#me').text(response.me);
|
|
$('#bm').text(response.bm);
|
|
$('#be').text(response.be);
|
|
$('#mb').text(response.mb);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
document.getElementById('ExportBTN1').addEventListener('click', function () {
|
|
// Select your table
|
|
var table = document.getElementById('caissierperf');
|
|
|
|
// Convert it to a workbook
|
|
var wb = XLSX.utils.table_to_book(table, {
|
|
sheet: "Feuille1"
|
|
});
|
|
|
|
// Export it
|
|
XLSX.writeFile(wb, 'export-caissier-performance.xlsx');
|
|
});
|
|
</script>
|
|
<!-- </div> -->
|
|
<?php endif; ?>
|
|
|
|
|
|
<!-- mecanicien -->
|
|
|
|
<?php if ($isMecanicien === true): ?>
|
|
<section class="content-header">
|
|
<h1>Rapport de performance d'un mécanicien</h1>
|
|
<ol class="breadcrumb">
|
|
<li><a href="#"><i class="fa fa-home"></i> Accueil</a></li>
|
|
<li class="active" onclick="window.history.back()" style="cursor: pointer;">Rapports</li>
|
|
</ol>
|
|
</section>
|
|
|
|
<section class="content">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body">
|
|
<!-- Product Details -->
|
|
<div class="row mt-4">
|
|
<div class="col-md-12 col-lg-12">
|
|
<div class="card shadow-sm border-0">
|
|
|
|
<div class="card-body">
|
|
<div class="row g-3 align-items-center mb-4" style="margin: 5px 0 5px 5px;">
|
|
<div class="col-md-3">
|
|
<label for="startDate" class="form-label">Date de début</label>
|
|
<input type="date" id="startDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="endDate" class="form-label">Date de fin</label>
|
|
<input type="date" id="endDate" class="form-control">
|
|
</div>
|
|
<div class="col-md-3 d-flex align-items-end">
|
|
<br>
|
|
<button id="filteredB1" class="btn btn-primary w-100">Filtrer
|
|
🔍</button>
|
|
<button id="ExportBTN1" class="btn btn-success w-100">Exporter
|
|
📤</button>
|
|
</div>
|
|
</div>
|
|
<table id="mecanicienperf" class="table table-hover table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th >Motos</th>
|
|
<th >Désignation</th>
|
|
<th >Numéro de série</th>
|
|
<th >Début de la réparation</th>
|
|
<th >Fin de la réparation</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<!-- Scripts -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
|
<script>
|
|
var manageTable;
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
|
manageTable = $('#mecanicienperf').DataTable({
|
|
'ajax': 'mecanicien/fetchMecanicienPerformances',
|
|
'order': [],
|
|
'pageLength': 5,
|
|
'lengthMenu': [
|
|
[5, 10, 25, 50, -1],
|
|
[5, 10, 25, 50, "Tout"]
|
|
],
|
|
columnDefs: [
|
|
{
|
|
targets: "_all", // ou un index de colonne, ou un tableau d’index
|
|
className: "text-left" // ou "dt-left" si tu utilises les classes par défaut de DataTables
|
|
}
|
|
],
|
|
"footerCallback": function (row, data, start, end, display) {
|
|
const api = this.api();
|
|
|
|
const parseNumber = (i) => typeof i === 'string'
|
|
? parseFloat(i.replace(/[^\d.-]/g, ''))
|
|
: typeof i === 'number'
|
|
? i
|
|
: 0;
|
|
|
|
const total = api
|
|
.column(2, { page: 'current' })
|
|
.data()
|
|
.reduce((a, b) => parseNumber(a) + parseNumber(b), 0);
|
|
|
|
$(api.column(2).footer()).html(total.toLocaleString('fr-FR'));
|
|
}
|
|
});
|
|
|
|
// Filtrage par dates
|
|
$('#filteredB1').on('click', function () {
|
|
const startDate = $('#startDate').val();
|
|
const endDate = $('#endDate').val();
|
|
|
|
manageTable.ajax.url('mecanicien/fetchMecanicienPerformances').load(function () {
|
|
const filteredData = [];
|
|
|
|
manageTable.rows().every(function () {
|
|
const data = this.data();
|
|
const repairDate = data[2].split(' ')[0]; // Début réparation
|
|
|
|
const isValid =
|
|
(!startDate && !endDate) ||
|
|
(startDate && endDate && repairDate >= startDate && repairDate <= endDate) ||
|
|
(startDate && !endDate && repairDate >= startDate) ||
|
|
(!startDate && endDate && repairDate <= endDate);
|
|
|
|
if (isValid) {
|
|
filteredData.push(data);
|
|
}
|
|
});
|
|
|
|
manageTable.clear().rows.add(filteredData).draw();
|
|
});
|
|
});
|
|
|
|
// Export en Excel
|
|
$('#ExportBTN1').on('click', function () {
|
|
const table = document.getElementById('mecanicienperf');
|
|
const wb = XLSX.utils.table_to_book(table, { sheet: "Feuille1" });
|
|
XLSX.writeFile(wb, 'export-performance-mecanicien.xlsx');
|
|
});
|
|
});
|
|
</script>
|
|
<?php endif; ?>
|
|
|
|
<!-- /.content-wrapper -->
|
|
</div>
|
|
|
|
<!-- js chart -->
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<script type="text/javascript">
|
|
window.onload = function() {
|
|
const ctx = document.getElementById("salesChart")?.getContext("2d");
|
|
if (!ctx) {
|
|
console.error("Canvas element not found!");
|
|
return;
|
|
}
|
|
|
|
const userData = <?= $isCommercial == true ? $user_order : '' ?>;
|
|
|
|
if (!Array.isArray(userData) || userData.length === 0) {
|
|
console.error("User data is empty or invalid", userData);
|
|
return;
|
|
}
|
|
|
|
const currentYear = new Date().getFullYear();
|
|
|
|
// Filter and sort data by date
|
|
const filteredData = userData
|
|
.filter(sale => new Date(sale.date_time).getFullYear() === currentYear)
|
|
.sort((a, b) => new Date(a.date_time) - new Date(b.date_time)); // Sort by date
|
|
|
|
if (filteredData.length === 0) {
|
|
console.warn("No data available for the current year.");
|
|
return;
|
|
}
|
|
|
|
let labels = filteredData.map(sale => sale.date_time);
|
|
let salesAmounts = filteredData.map(sale => parseFloat(sale.net_amount));
|
|
|
|
new Chart(ctx, {
|
|
type: "line",
|
|
data: {
|
|
labels: labels,
|
|
datasets: [{
|
|
label: "Montant (Net)",
|
|
data: salesAmounts,
|
|
backgroundColor: "rgba(54, 162, 235, 0.5)",
|
|
borderColor: "rgba(54, 162, 235, 1)",
|
|
borderWidth: 2,
|
|
fill: false,
|
|
tension: 0.3
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
scales: {
|
|
x: {
|
|
title: {
|
|
display: true,
|
|
text: "Date & Heure"
|
|
}
|
|
},
|
|
y: {
|
|
beginAtZero: true,
|
|
title: {
|
|
display: true,
|
|
text: "Montant (Ar)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
};
|
|
</script>
|
|
<!-- piechart for order per store -->
|
|
<script>
|
|
$(document).ready(function() {
|
|
$("#dashboardMainMenu").addClass('active');
|
|
var ctx = document.getElementById('storeChart').getContext('2d');
|
|
|
|
var paymentChart = new Chart(ctx, {
|
|
type: 'pie',
|
|
data: {
|
|
labels: <?= $labelStore ?>,
|
|
datasets: [{
|
|
label: 'Pourcentage de Transactions',
|
|
data: <?= $totalPerStore ?>,
|
|
backgroundColor: ['#3498db', '#2ecc71', '#B88A2F'],
|
|
borderColor: ['#2980b9', '#27ae60', '#f39c12'],
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
tooltip: {
|
|
callbacks: {
|
|
label: function(tooltipItem) {
|
|
return tooltipItem.raw.toFixed(2) + '%';
|
|
}
|
|
}
|
|
},
|
|
legend: {
|
|
position: 'bottom',
|
|
labels: {
|
|
generateLabels: function(chart) {
|
|
return chart.data.labels.map(function(label, i) {
|
|
return {
|
|
text: `${label} (${chart.data.datasets[0].data[i].toFixed(2)}%)`,
|
|
fillStyle: chart.data.datasets[0].backgroundColor[i]
|
|
};
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// document.addEventListener("DOMContentLoaded", function() {
|
|
let orders = <?= $marques_total ?>; // Orders from PHP
|
|
let brandNames = <?= $marques ?>; // All brands from PHP
|
|
|
|
// Step 1: Count occurrences of each brand
|
|
let brandCount = {};
|
|
orders.forEach(order => {
|
|
let brand = order.name;
|
|
brandCount[brand] = (brandCount[brand] || 0) + 1;
|
|
});
|
|
console.log(brandCount);
|
|
|
|
// Step 2: Convert to array and sort by count (descending)
|
|
let sortedBrands = Object.entries(brandCount)
|
|
.sort((a, b) => b[1] - a[1]) // Sort by count descending
|
|
.slice(0, 5); // Keep only top 5
|
|
|
|
// Step 3: Prepare data for the chart
|
|
let labels = sortedBrands.map(item => item[0]); // Brand names
|
|
let data = sortedBrands.map(item => item[1]); // Order counts
|
|
console.log(labels);
|
|
|
|
// Step 4: Create the Pie Chart
|
|
let ctx2 = document.getElementById('MotosChart').getContext('2d');
|
|
new Chart(ctx2, {
|
|
type: 'pie',
|
|
data: {
|
|
labels: labels,
|
|
datasets: [{
|
|
label: 'Top 5 Marques',
|
|
data: data,
|
|
backgroundColor: [
|
|
'#FF6384', '#36A2EB', '#FFCE56', '#4CAF50', '#8E44AD'
|
|
],
|
|
hoverOffset: 4
|
|
}]
|
|
}
|
|
});
|
|
// });
|
|
|
|
});
|
|
</script>
|