radiantrh/Vue/Ficheadherent/index.php
2026-03-26 09:24:38 +00:00

702 lines
31 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// $this->titre = "INTER-SANTE - Fiche Adhérent";
$codeTypeAvenant = $_SESSION['codeTypeAvenant_C'];
$estsupprimable_0 = false;
$garantieArchive = $_SESSION['garantieArchive_C'];
$estsupprimable = false;
$primeArchiveAdh = $this->nettoyer($adherent['primeArchive']);
$estsupprimableAdh = ($primeArchiveAdh=="0");
//$superUser = $_SESSION['superUser'];
$idAdherent = $this->nettoyer($adherent['idAdherent']);
$adherentRetire = $adherent['sorti'];
$dateSortieAdherent = $adherent['dateSortieAdherent'];
$controlerPlafondAdherent = ($_SESSION['controlerPlafondAdherent']>0);
$codeTypeContrat = $_SESSION['codeTypeContrat'];
$idApporteur = $this->nettoyer($adherent['idApporteur']);
$libelleApporteur = $this->nettoyer($adherent['libelleApporteur']);
$typeecheancier = $this->nettoyer($adherent['typeecheancier']);
if (est_anglophone())
{
$typeecheancier = $this->nettoyer($adherent['typeecheancierEng']);
}
$tauxInteretEcheancier = $this->nettoyer($adherent['tauxInteretEcheancier']);
?>
<script type="text/javascript">
</script>
<INPUT class="sr-only" TYPE="text" id="garantieArchive_C" name="garantieArchive_C" value="<?= $_SESSION['garantieArchive_C'] ?>">
<INPUT class="sr-only" TYPE="text" id="primeArchive" name="primeArchive" value="<?= $adherent['primeArchive'] ?>" >
<INPUT class="sr-only" TYPE="text" id="remplacementAdherent" name="remplacementAdherent" value="<?= $adherent['remplacementAdherent'] ?>" >
<INPUT class="sr-only" TYPE="text" id="remplace" name="remplace" value="<?= $adherent['remplace'] ?>" >
<INPUT class="sr-only" TYPE="text" id="remplacant" name="remplacant" value="<?= $adherent['remplacant'] ?>" >
<INPUT class="sr-only" TYPE="text" id="idApporteur" name="idApporteur" value="<?= $idApporteur ?>" >
<INPUT class="sr-only" TYPE="text" id="adherentRetire" name="adherentRetire" value="<?= $adherentRetire ?>" >
<div id="div_adherent" class="container-fluid py-1 animate__animated animate__fadeIn">
<h1 class="text-primary"><i class="fas fa-id-card me-2"></i><?= _('Fiche adhérent') ?></h1>
<div class="card-header d-flex justify-content-between align-items-center py-1">
<h5 class="mb-0 fw-bold">
<?= _("POLICE") ?> : <span class="text-secondary"><?= $this->nettoyer($_SESSION['numeroPolice_C']) ?></span>
<span class="ms-3 badge bg-primary text-light small fw-normal">ID: <?= $this->nettoyer($_SESSION['idPolice_C']) ?></span>
</h5>
</div>
<form name="formficheadehrent" id="formficheadehrent" method="POST" class="container-fluid py-1">
<input type="hidden" id="codeEtatFacturation" name="codeEtatFacturation" value="<?= $adherent['codeEtatFacturation'] ?>">
<input type="hidden" id="numeroBeneficiaire" name="numeroBeneficiaire" value="<?= $adherent['numeroBeneficiaire'] ?>">
<input type="hidden" id="codeEtatAdherent" name="codeEtatAdherent" value="<?= $adherent['codeEtatAdherent'] ?>">
<?php if ($adherentRetire == "1") : ?>
<div class="alert alert-danger d-flex align-items-center mb-4 shadow-sm" role="alert">
<i class="fas fa-exclamation-triangle me-3 fa-2x"></i>
<div>
<h4 class="alert-heading mb-0"><?= _("Adhérent sorti le") . " : " . dateLang($dateSortieAdherent, $_SESSION['lang']) ?></h4>
</div>
</div>
<?php endif; ?>
<div class="card shadow-sm mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="fas fa-user-circle me-2"></i><?= _("Informations sur l'adhérent") ?> : <span class="badge bg-light text-primary"><?= $this->nettoyer($adherent['numeroAdherent']) ?></span></h5>
</div>
<div class="card-body bg-light">
<div class="row g-3">
<div class="col-md-4">
<label class="form-label small text-uppercase fw-bold"><?= _("Nom & Prénoms") ?></label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-id-card"></i></span>
<input type="text" class="form-control" value="<?= $this->nettoyer($adherent['nom']) ?> <?= $this->nettoyer($adherent['prenoms']) ?>" readonly>
</div>
</div>
<div class="col-md-4">
<label class="form-label small text-uppercase fw-bold"><?= _("Collège") ?></label>
<input type="text" class="form-control" value="<?= $this->nettoyer($adherent['libelleCollege']) ?>" readonly>
</div>
<div class="col-md-4">
<label class="form-label small text-uppercase fw-bold"><?= _("Contact") ?></label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-phone"></i></span>
<input type="text" class="form-control" value="<?= $this->nettoyer($adherent['telephonePortable']) ?>" readonly>
</div>
</div>
<div class="col-md-4">
<label class="form-label small text-uppercase fw-bold"><?= _("E-mail") ?></label>
<input type="email" class="form-control" value="<?= $this->nettoyer($adherent['email']) ?>" readonly>
</div>
<div class="col-md-8">
<label class="form-label small text-uppercase fw-bold"><?= _("Localisation") ?></label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-map-marker-alt"></i></span>
<input type="text" class="form-control" value="<?= $this->nettoyer($adherent['pays']) ?> / <?= $this->nettoyer($adherent['ville']) ?> / <?= $this->nettoyer($adherent['localite']) ?>" readonly>
</div>
</div>
<div class="col-md-12 mt-3">
<?php if($nombreGed > 0): ?>
<div class="alert alert-success d-flex align-items-center shadow-sm border-0 py-3" style="border-radius: 10px;">
<i class="fas fa-check-double fa-2x me-3"></i>
<div class="flex-grow-1">
<h6 class="mb-1 fw-bold fs-5">
<?= est_anglophone() ? 'Identity Documents Verified' : 'Documents didentité vérifiés'; ?>
</h6>
<span class="small d-block opacity-75" style="font-size: 10.5pt;">
<?= est_anglophone()
? 'The members digital folder is up to date (ID card, Passport, Birth certificate...).'
: 'Le dossier numérique de ladhérent est à jour (CNI, Passeport, Acte de naissance...).'; ?>
</span>
</div>
<a href="Gedadherent/" class="btn btn-success btn-sm fw-bold ms-3 px-3">
<i class="fas fa-folder-open me-2"></i><?= _("Consulter la GED") ?>
</a>
</div>
<?php else: ?>
<div class="alert alert-danger d-flex align-items-center shadow-sm border-0 py-3 animate__animated animate__pulse animate__infinite" style="border-radius: 10px;">
<i class="fas fa-exclamation-triangle fa-2x me-3"></i>
<div class="flex-grow-1">
<h6 class="mb-1 fw-bold fs-5">
<?= est_anglophone() ? 'Missing Documents' : 'Documents manquants'; ?>
</h6>
<span class="small d-block fw-bold" style="font-size: 10.5pt;">
<?= est_anglophone()
? 'Action required: Please upload the identity documents to complete this members file.'
: 'Action requise : Veuillez joindre les pièces justificatives pour finaliser ce dossier.'; ?>
</span>
</div>
<a href="Gedadherent/" class="btn btn-danger btn-sm fw-bold ms-3 px-3 shadow-sm">
<i class="fas fa-upload me-2"></i><?= _("Ouvrir la GED") ?>
</a>
</div>
<?php endif; ?>
</div>
</div>
<?php if ($controlerPlafondAdherent): ?>
<hr class="my-4">
<div class="row g-3 text-center">
<div class="col-md-4">
<div class="p-3 border rounded bg-white shadow-sm">
<div class="small fw-bold text-primary text-uppercase"><?= _("Plafond Famille") ?></div>
<div class="h4 mb-0 text-primary fw-bold"><?= format_N($limite_adherent['plafondAdherent']) ?></div>
</div>
</div>
<div class="col-md-4">
<div class="p-3 border rounded bg-white shadow-sm border-danger">
<div class="small fw-bold text-danger text-uppercase"><?= _("Consommations") ?></div>
<div class="h4 mb-0 text-danger fw-bold"><?= format_N($limite_adherent['consommationAdherent']) ?></div>
</div>
</div>
<div class="col-md-4">
<div class="p-3 border rounded bg-success text-white shadow-sm">
<div class="small fw-bold text-uppercase"><?= _("Solde Disponible") ?></div>
<div class="h4 mb-0 fw-bold"><?= format_N($limite_adherent['soldeAdherent']) ?></div>
</div>
</div>
</div>
<?php endif; ?>
</div>
</div>
<?php if ($codeTypeContrat == "F"): ?>
<div class="card shadow-sm mb-4 border-info">
<div class="card-header bg-info text-dark fw-bold">
<i class="fas fa-file-invoice-dollar me-2"></i><?= _("Récapitulatif des primes") ?>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-sm table-hover mb-0 align-middle">
<thead class="table-light">
<tr>
<th class="text-center"><?= _("Prime HT") ?></th>
<th class="text-center"><?= _("Taxes") ?></th>
<th class="text-center"><?= _("Prime TTC") ?></th>
<th class="text-center"><?= _("Nb Échéances") ?></th>
<th class="text-center"><?= _("Part Assureur") ?></th>
<th class="text-center"><?= _("Part Tiers") ?></th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center fw-bold"><?= format_N($adherent['primeHt']) ?></td>
<td class="text-center text-muted"><?= format_N($adherent['taxe']) ?></td>
<td class="text-center fw-bold text-primary"><?= format_N($adherent['primeTtc']) ?></td>
<td class="text-center"><?= $adherent['nbEcheance'] ?></td>
<td class="text-center"><span class="badge bg-primary"><?= format_N($adherent['partAssureur']) ?></span></td>
<td class="text-center"><span class="badge bg-danger"><?= format_N($adherent['partTiers']) ?></span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<?php endif; ?>
<div class="card shadow-sm mb-4">
<div class="card-header">
<h5 class="mb-0"><i class="fas fa-users me-2"></i><?= _('Composition de la famille') ?></h5>
</div>
<div class="card-body p-0">
<div class="table-responsive" style="max-height: 400px; overflow-y: auto;">
<table class="table table-hover table-striped mb-0 align-middle shadow-sm">
<thead class="table-dark sticky-top">
<tr class="small">
<th><?= _("Photo") ?></th>
<th><?= _("N° Bénéf.") ?></th>
<th><?= _("Nom & Prénoms") ?></th>
<th class="text-center"><?= _("Sexe") ?></th>
<th><?= _("Lien") ?></th>
<th class="text-center"><?= _("Âge") ?></th>
<th class="text-end"><?= _("Prime HT") ?></th>
<th class="text-end"><?= _("Prime TTC") ?></th>
<th class="text-center"><?= _("État") ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($beneficiaires as $beneficiaire):
$photoPath = ($beneficiaire['faceRegistered'] == "1") ? $_SESSION['dossierPhoto_C'].$_SESSION['dossierSociete'].'/Photos/'.$beneficiaire['lienPhoto'] : '';
$faceRegistered = $this->nettoyer($beneficiaire['faceRegistered']);
?>
<tr class="pointer-cursor" onclick="selectionner_beneficiaire(<?= $beneficiaire['idBeneficiaire'] ?>,'<?= $beneficiaire['numeroBeneficiaire'] ?>'); afficher_beneficiaire_id();">
<td class="text-center">
<?php if($faceRegistered == "1"): ?>
<img src="<?= $photoPath ?>" class="rounded-circle border" width="32" height="32" alt="Photo">
<?php else: ?>
<i class="fas fa-user-circle photo-zoom" style="color: #ccc; font-size: 32px;"></i>
<?php endif; ?>
</td>
<td><span class="badge bg-secondary text-light border"><?= $beneficiaire['numeroBeneficiaire'] ?></span></td>
<td class="fw-bold"><?= $this->nettoyer($beneficiaire['nomBeneficiaire']) ?> <?= $this->nettoyer($beneficiaire['prenomsBeneficiaire']) ?></td>
<td class="text-center"><?= $beneficiaire['sexe'] ?></td>
<td><?= (est_anglophone()) ? $beneficiaire['LienParenteEng'] : $beneficiaire['LienParente'] ?></td>
<td class="text-center"><?= $beneficiaire['age'] ?> ans</td>
<td class="text-end"><?= format_N($beneficiaire['primeHt']) ?></td>
<td class="text-end fw-bold"><?= format_N($beneficiaire['primeTtc']) ?></td>
<td class="text-center">
<span class="badge <?= ($beneficiaire['codeEtatBeneficiaire'] == 'V') ? 'bg-success' : 'bg-danger' ?>">
<?= $beneficiaire['codeEtatBeneficiaire'] ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot class="table-light fw-bold text-end">
<tr>
<td colspan="6" class="text-center"><?= _("TOTAL FAMILLE") ?></td>
<td><?= format_N($totalbeneficiaires['primeHt']) ?></td>
<td class="text-primary"><?= format_N($totalbeneficiaires['primeTtc']) ?></td>
<td></td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<div class="card shadow-sm">
<div class="card-header">
<i class="fas fa-shield-alt me-2"></i><?= _("Limites et Garanties de la famille") ?>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-sm table-hover align-middle mb-0">
<thead class="bg-light">
<tr class="small text-uppercase">
<th class="ps-3"><?= _("Garantie") ?></th>
<th class="text-center"><?= _("Plafond") ?></th>
<th class="text-center"><?= _("Conso.") ?></th>
<th class="text-center"><?= _("Solde") ?></th>
<th class="text-center"><?= _("Par tête") ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($garantieadherents as $garantieadherent): ?>
<tr>
<td class="ps-3 fw-bold"><?= $this->nettoyer($garantieadherent['garantie']) ?></td>
<td class="text-center fw-bold"><?= format_N($garantieadherent['plafond']) ?></td>
<td class="text-center text-danger"><?= ($garantieadherent['champApplication'] != '1') ? format_N($garantieadherent['consommation']) : '-' ?></td>
<td class="text-center fw-bold text-success"><?= ($garantieadherent['champApplication'] != '1') ? format_N($garantieadherent['solde']) : '-' ?></td>
<td class="text-center text-primary">
<i class="fas <?= ($garantieadherent['champApplication'] == '1') ? 'fa-check-circle' : 'fa-minus text-muted' ?>"></i>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</form>
<!-- Responsive Area Chart -->
<div class="row mt-2">
<div class="col-xl-8 col-lg-7 mb-2">
<div class="card shadow h-100">
<div class="card-header py-1 d-flex flex-column flex-md-row justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary"><?= _("Dépenses mensuelles") ?></h6>
<div class="mt-2 mt-md-0">
<button id="exportTrendBtn" class="btn btn-sm btn-danger mr-2">
<i class="fas fa-download"></i> PDF
</button>
<small class="text-muted"><?= _("Évolution sur 12 mois") ?></small>
</div>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height:300px; width:100%">
<canvas id="expenseTrendChart"></canvas>
</div>
</div>
</div>
</div>
<!-- Responsive Pie Chart -->
<div class="col-xl-4 col-lg-5 mb-2">
<div class="card shadow h-100">
<div class="card-header py-1 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary"><?= _("Dépenses par lien parenté") ?></h6>
<button id="exportPieBtn" class="btn btn-sm btn-danger">
<i class="fas fa-download"></i> PDF
</button>
</div>
<div class="card-body d-flex flex-column">
<div class="chart-container" style="position: relative; height:250px; width:100%">
<canvas id="expenseDistributionChart"></canvas>
</div>
<div id="pieChartLegend" class="mt-3 text-center"></div>
<div class="mt-auto pt-3">
<small class="text-muted"><?= _("Répartition en pourcentage") ?></small>
</div>
</div>
</div>
</div>
</div>
<!-- Bar Chart Section -->
<div class="row mt-4">
<div class="col-12 mb-2">
<div class="card shadow h-100">
<div class="card-header py-1 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary"><?= _("Dépenses par garantie") ?></h6>
<button id="exportBarBtn" class="btn btn-sm btn-danger">
<i class="fas fa-download"></i> PDF
</button>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height:400px; width:100%">
<canvas id="depensesChart"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.pointer-cursor { cursor: pointer; transition: background 0.2s; }
.pointer-cursor:hover { background-color: #f1f8ff !important; }
.sticky-top { top: -1px; z-index: 10; }
.table-responsive { border-radius: 0.375rem; }
.input-group-text { background-color: #f8f9fa; color: #6c757d; }
input[readonly] { cursor: default; }
</style>
<script>
// Configuration commune
(function() {
// Format numérique simplifié (sans devise)
const formatMoney = (value) => {
return new Intl.NumberFormat('fr-FR').format(value);
};
// Format pourcentage sécurisé
const formatPercentage = (value, total) => {
if (total === 0) {
return '0%'; // ou 'N/A' si tu préfères
}
const percentage = (value * 100 / total).toFixed(1);
return percentage + '%';
};
// Détection mobile
const isMobile = window.matchMedia("(max-width: 768px)").matches;
// Génération des couleurs
const generateColors = (count) => {
const palette = [
'#4e73df', '#1cc88a', '#36b9cc', '#f6c23e',
'#e74a3b', '#858796', '#5a5c69', '#3a3b45',
'#2e59a9', '#17a673', '#2c9faf', '#dda20a'
];
return palette.slice(0, count).concat(
Array.from({length: Math.max(0, count - palette.length)}, (_, i) => {
const hue = Math.floor(360 * (i / Math.max(1, count - palette.length)));
return `hsl(${hue}, 70%, 60%)`;
})
);
};
// Fonction pour générer une légende personnalisée
function generateCustomLegend(chart, containerId) {
const legendContainer = document.getElementById(containerId);
legendContainer.innerHTML = '';
const items = chart.data.datasets[0].data.map((value, i) => {
const total = chart.data.datasets[0].data.reduce((a, b) => a + b, 0);
const percentage = formatPercentage(value, total);
return `
<div class="d-inline-block mx-2 my-1">
<span class="legend-color" style="
display: inline-block;
width: 12px;
height: 12px;
background-color: ${chart.data.datasets[0].backgroundColor[i]};
border: 1px solid #fff;
vertical-align: middle;
"></span>
<span class="legend-text small ml-1">
${chart.data.labels[i]}: ${formatMoney(value)} (${percentage})
</span>
</div>
`;
});
legendContainer.innerHTML = items.join('');
}
// Fonction pour exporter un graphique en PDF
function exportChartToPDF(chartId, fileName) {
const { jsPDF } = window.jspdf;
const canvas = document.getElementById(chartId);
html2canvas(canvas).then(canvasImage => {
const imgData = canvasImage.toDataURL('image/png');
const pdf = new jsPDF({
orientation: canvasImage.width > canvasImage.height ? 'landscape' : 'portrait'
});
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
const ratio = canvasImage.height / canvasImage.width;
let imgWidth = pageWidth - 20;
let imgHeight = imgWidth * ratio;
if (imgHeight > pageHeight - 20) {
imgHeight = pageHeight - 20;
imgWidth = imgHeight / ratio;
}
pdf.addImage(imgData, 'PNG',
(pageWidth - imgWidth) / 2,
(pageHeight - imgHeight) / 2,
imgWidth,
imgHeight
);
pdf.save(fileName + '.pdf');
});
}
// Graphique d'évolution des dépenses
const dataMois = <?= $dataConsoParMois ?>;
const trendCtx = document.getElementById('expenseTrendChart').getContext('2d');
const trendChart = new Chart(trendCtx, {
type: 'line',
data: {
labels: dataMois.mois,
datasets: [{
label: '<?= _("Montant dépensé") ?>',
data: dataMois.consos,
backgroundColor: 'rgba(78, 115, 223, 0.05)',
borderColor: 'rgba(78, 115, 223, 1)',
borderWidth: 2,
pointBackgroundColor: 'rgba(78, 115, 223, 1)',
pointRadius: isMobile ? 3 : 4,
pointHoverRadius: 6,
fill: true,
tension: 0.3
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: function(context) {
return context.dataset.label + ': ' + formatMoney(context.parsed.y);
}
}
}
},
scales: {
x: {
grid: {
display: false
},
ticks: {
maxRotation: isMobile ? 45 : 0,
autoSkip: true,
maxTicksLimit: isMobile ? 6 : 12
}
},
y: {
beginAtZero: false,
ticks: {
callback: function(value) {
return formatMoney(value);
}
},
grid: {
color: 'rgba(0, 0, 0, 0.05)'
}
}
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
}
}
});
// Graphique de répartition
const dataLiens = <?= $dataConsoParLiens ?>;
const distributionCtx = document.getElementById('expenseDistributionChart').getContext('2d');
const distributionChart = new Chart(distributionCtx, {
type: 'pie',
data: {
labels: dataLiens.lienparente,
datasets: [{
data: dataLiens.consos_liens,
backgroundColor: generateColors(<?= $nbreLienParente; ?>),
borderColor: '#fff',
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
datalabels: {
formatter: (value, ctx) => {
const sum = ctx.chart.data.datasets[0].data.reduce((a, b) => a + b, 0);
return formatPercentage(value, sum);
},
color: '#fff',
font: {
weight: 'bold',
size: isMobile ? 10 : 12
}
},
tooltip: {
callbacks: {
label: function(context) {
const label = context.label || '';
const value = context.raw || 0;
const sum = context.dataset.data.reduce((a, b) => a + b, 0);
const percentage = formatPercentage(value, sum);
return `${label}: ${formatMoney(value)} (${percentage})`;
}
}
}
},
cutout: isMobile ? '60%' : '50%'
},
plugins: [ChartDataLabels]
});
// Graphique des dépenses par garantie
const dataConso = <?= $dataConsoParGaranties ?>;
const barCtx = document.getElementById('depensesChart').getContext('2d');
const barChart = new Chart(barCtx, {
type: 'bar',
data: {
labels: dataConso.garanties,
datasets: [{
label: '<?= _('Dépenses')?>',
data: dataConso.depenses,
backgroundColor: 'rgba(54, 162, 235, 0.7)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
annotation: {
annotations: dataConso.plafonds.map((plafond, index) => {
if (plafond === null) return null;
return {
type: 'line',
yMin: plafond,
yMax: plafond,
borderColor: 'rgba(255, 99, 132, 0.7)',
borderWidth: 2,
borderDash: [6, 6],
label: {
content: `<?= _('Plafond').': '?> ${formatMoney(plafond)}`,
enabled: true,
position: 'right'
}
};
}).filter(annotation => annotation !== null)
},
legend: {
display: false
},
tooltip: {
callbacks: {
label: function(context) {
const plafond = dataConso.plafonds[context.dataIndex];
let tooltip = `<?= _('Dépenses').':'?> ${formatMoney(context.parsed.y)}`;
if (plafond !== null) {
const pourcentage = Math.min(100, Math.round((context.parsed.y / plafond) * 100));
tooltip += ` (${pourcentage}% <?= _('du plafond')?>)`;
} else {
tooltip += ' <?= _('(plafond illimité)')?>';
}
return tooltip;
}
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: '<?= _("Montant des dépenses") ?>',
font: {
weight: 'bold'
}
},
ticks: {
callback: function(value) {
return formatMoney(value);
}
},
suggestedMax: Math.max(...dataConso.depenses) * 1.5
},
x: {
title: {
display: true,
text: '<?= _('Garanties')?>',
font: {
weight: 'bold'
}
},
grid: {
display: false
}
}
}
}
});
// Générer la légende au chargement et lors du redimensionnement
generateCustomLegend(distributionChart, 'pieChartLegend');
window.addEventListener('resize', function() {
generateCustomLegend(distributionChart, 'pieChartLegend');
});
// Boutons d'export PDF
document.getElementById('exportTrendBtn').addEventListener('click', () => {
exportChartToPDF('expenseTrendChart', 'evolution_depenses_mensuelles');
});
document.getElementById('exportPieBtn').addEventListener('click', () => {
exportChartToPDF('expenseDistributionChart', 'repartition_depenses_parente');
});
document.getElementById('exportBarBtn').addEventListener('click', () => {
exportChartToPDF('depensesChart', 'depenses_par_garantie');
});
})();
</script>