radiantrh/Vue/Fichebeneficiaire/index.php
2026-03-26 10:50:59 +00:00

702 lines
26 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 Bénéficiaire";
$datejour = $this->datejour;
$estcouvert = ($_SESSION['dateEcheancePolice_C']>=$datejour);
$sorti = $this->nettoyer($beneficiaire['sorti']);
$dateSortieBeneficiaire = $this->nettoyer($beneficiaire['dateSortieBeneficiaire']);
$estsorti = false;
// if($dateSortieBeneficiaire>"2000-01-01")
if($sorti=="1")
{
$estsorti = ($dateSortieBeneficiaire<=$datejour);
$estcouvert = ($estcouvert && ($dateSortieBeneficiaire>$datejour));
}
$dateEffetCouvert = $_SESSION['dateEffetCouvert'];
if (est_anglophone())
{
$produit = $beneficiaire['produitEng'];
$naturepiece = $beneficiaire['naturepieceEng'];
$lienparente = $beneficiaire['lienparenteEng'];
$motifsortie = $beneficiaire['motifsortieEng'];
$etatbeneficiaire = $beneficiaire['etatbeneficiaireEng'];
}
else
{
$produit = $beneficiaire['produit'];
$naturepiece = $beneficiaire['naturepiece'];
$lienparente = $beneficiaire['lienparente'];
$motifsortie = $beneficiaire['motifsortie'];
$etatbeneficiaire = $beneficiaire['etatbeneficiaire'];
}
$controlerPlafondAdherent = ($_SESSION['controlerPlafondAdherent']>0);
$controlerPlafondBeneficiaire = ($_SESSION['controlerPlafondBeneficiaire']>0);
$codeTypeContrat = $_SESSION['codeTypeContrat'];
$idApporteur = $this->nettoyer($beneficiaire['idApporteur']);
$libelleApporteur = $this->nettoyer($beneficiaire['libelleApporteur']);
$typeecheancier = $this->nettoyer($beneficiaire['typeecheancier']);
if (est_anglophone())
{
$typeecheancier = $this->nettoyer($beneficiaire['typeecheancierEng']);
}
$tauxInteretEcheancier = $this->nettoyer($beneficiaire['tauxInteretEcheancier']);
$photoAssureCrypte = $_SESSION['photoAssureCrypte'];
$faceRegistered = $this->nettoyer($beneficiaire['faceRegistered']);
$face_confirmee = $_SESSION['okId_face'];
$fingerActif = $_SESSION['fingerActif'];
$faceActif = $_SESSION['faceActif'];
?>
<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="<?= $beneficiaire['primeArchive'] ?>" >
<INPUT class="sr-only" TYPE="text" id="finger_id_C" name="finger_id_C" value="<?= $_SESSION['finger_id_C'] ?>">
<INPUT class="sr-only" TYPE="text" id="faceRegistered" name="faceRegistered" value="<?= $faceRegistered ?>">
<button class="sr-only" id="btn_pop_save_face" name="btn_pop_save_face" type="button" data-bs-toggle="modal" data-bs-target="#pop_rec_faciale" > </button>
<div id="div_urlFace">
<input class="sr-only" type="text" id="urlFace" name="urlFace" value="">
</div>
<div id="div_wait_face">
</div>
<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 bénéficiaire') ?></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="formfichebeneficiaire" id="formfichebeneficiaire" method="POST" class="container-fluid py-3">
<div class="d-flex flex-wrap justify-content-between align-items-center mb-4 bg-white p-4 rounded shadow-sm border-start border-primary border-5">
<div class="d-flex align-items-center mb-2 mb-lg-0">
<div class="bg-primary-subtle text-primary rounded-circle p-3 me-3 d-none d-md-flex">
<i class="fa-solid fa-user-gear fa-2x"></i>
</div>
<div>
<h4 class="h4 mb-1 text-dark fw-bold">
<?= _("Bénéficiaire") ?> : <span class="text-primary"><?= $beneficiaire['numeroBeneficiaire'] ?></span>
</h4>
<div class="d-flex align-items-center text-muted small">
<i class="fa-regular fa-calendar-check me-2"></i>
<?= _("Date Effet") ?> : <span class="fw-bold ms-1"><?= dateLang($this->nettoyer($beneficiaire['dateEffet']), $_SESSION['lang']) ?></span>
</div>
</div>
</div>
<div class="flex-grow-1 px-lg-4 my-3 my-lg-0" style="max-width: 600px;">
<?php if($nombreGed > 0): ?>
<div class="alert alert-success d-flex align-items-center m-0 py-2 px-3 border-0 shadow-sm" style="border-radius: 12px; background-color: #e8f5e9;">
<i class="fas fa-check-circle fa-2x text-success me-3"></i>
<div class="flex-grow-1">
<h6 class="mb-0 fw-bold small text-success">
<?= est_anglophone() ? 'Verified Folder' : 'Dossier Vérifié'; ?>
</h6>
<small class="d-block text-dark opacity-75" style="font-size: 8.5pt;">
<?= est_anglophone() ? 'Identity documents are up to date.' : 'Les documents didentité sont à jour.'; ?>
</small>
</div>
<a href="Gedbeneficiaireprod/" class="btn btn-success btn-sm rounded-pill px-3 ms-2">
<i class="fas fa-eye me-1"></i>
</a>
</div>
<?php else: ?>
<div class="alert alert-danger d-flex align-items-center m-0 py-2 px-3 border-0 shadow-sm animate__animated animate__pulse animate__infinite" style="border-radius: 12px; background-color: #ffebee;">
<i class="fas fa-exclamation-circle fa-2x text-danger me-3"></i>
<div class="flex-grow-1">
<h6 class="mb-0 fw-bold small text-danger">
<?= est_anglophone() ? 'Incomplete File' : 'Dossier Incomplet'; ?>
</h6>
<small class="d-block text-dark fw-bold" style="font-size: 8.5pt;">
<?= est_anglophone() ? 'Missing ID documents.' : 'Pièces didentité manquantes.'; ?>
</small>
</div>
<a href="Gedbeneficiaireprod/" class="btn btn-danger btn-sm rounded-pill px-3 ms-2 shadow-sm">
<i class="fas fa-upload me-1"></i>
</a>
</div>
<?php endif; ?>
</div>
<div class="text-end">
<?php
$statusClass = "bg-danger"; $statusIcon = "fa-circle-xmark"; $statusText = _("Inconnu");
if ($dateEffetCouvert == "0") {
$statusText = _("Non renouvelé");
$statusIcon = "fa-calendar-minus";
}
elseif ($estcouvert) {
if ($beneficiaire['codeEtatBeneficiaire'] == "V") {
$statusClass = "bg-success";
$statusIcon = "fa-shield-check";
$statusText = $etatbeneficiaire;
}
else {
$statusText = $etatbeneficiaire;
$statusIcon = "fa-circle-exclamation";
}
} elseif ($estsorti) {
$statusText = _("Retiré");
$statusIcon = "fa-user-slash";
}
else {
$statusText = _("Expiré");
$statusIcon = "fa-clock-rotate-left";
}
?>
<div class="small text-muted text-uppercase fw-bold mb-1" style="font-size: 7pt; letter-spacing: 1px;"><?= _("Statut Couverture") ?></div>
<span class="badge <?= $statusClass ?> fs-6 shadow-sm p-2 px-4 rounded-pill d-inline-flex align-items-center">
<i class="fa-solid <?= $statusIcon ?> me-2"></i> <?= $statusText ?>
</span>
</div>
</div>
<div class="row g-4">
<div class="col-lg-8">
<div class="card shadow-sm h-100">
<div class="card-header bg-white fw-bold"><i class="fa-solid fa-user me-2"></i><?= _("Informations Personnelles") ?></div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label small text-uppercase fw-bold"><?= _("Nom & Prénoms") ?></label>
<input class="form-control bg-light fw-bold" type="text" value="<?= $beneficiaire['nomBeneficiaire'] . ' ' . $beneficiaire['prenomsBeneficiaire'] ?>" readonly>
</div>
<div class="col-md-3">
<label class="form-label small text-uppercase fw-bold"><?= _("Genre") ?></label>
<input class="form-control bg-light text-center" type="text" value="<?= $beneficiaire['sexe'] ?>" readonly>
</div>
<div class="col-md-3">
<label class="form-label small text-uppercase fw-bold"><?= _("Groupe Sanguin") ?></label>
<input class="form-control bg-light text-center fw-bold text-danger" type="text" value="<?= $beneficiaire['codeGroupeSanguin'] ?>" readonly>
</div>
<div class="col-md-4">
<label class="form-label small text-uppercase fw-bold"><?= _("Naissance & Âge") ?></label>
<input class="form-control bg-light" type="text" value="<?= dateLang($this->nettoyer($beneficiaire['dateNaissance']), $_SESSION['lang']).' ('.$beneficiaire['age'].' ans)' ?>" readonly>
</div>
<div class="col-md-4">
<label class="form-label small text-uppercase fw-bold"><?= _("Lien Parenté") ?></label>
<input class="form-control bg-light" type="text" value="<?= $lienparente ?>" readonly>
</div>
<div class="col-md-4">
<label class="form-label small text-uppercase fw-bold"><?= _("Téléphone") ?></label>
<input class="form-control bg-light" type="tel" value="<?= $beneficiaire['telephonePortable'] ?>" readonly>
</div>
<div class="col-md-6">
<label class="form-label small text-uppercase fw-bold"><?= _("Pièce d'identité") ?></label>
<div class="input-group">
<span class="input-group-text small"><?= $naturepiece ?></span>
<input class="form-control bg-light" type="text" value="<?= $beneficiaire['numeroPiece'] ?>" readonly>
</div>
</div>
<div class="col-md-6">
<label class="form-label small text-uppercase fw-bold"><?= _("Collège / Produit") ?></label>
<input class="form-control bg-light text-primary fw-bold" type="text" value="<?= $beneficiaire['libelleCollege'] ?>" readonly>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow-sm border-0 mb-3">
<div class="card-body text-center p-4">
<div class="position-relative d-inline-block mb-3">
<?php if($faceRegistered == "1"): ?>
<img src="<?=$photoAssureCrypte?>" class="img-thumbnail rounded-circle shadow" style="width: 150px; height: 150px; object-fit: cover;">
<button type="button" onClick="ebene_init_confirm_photo_face();" class="btn btn-sm btn-success position-absolute bottom-0 end-0 rounded-circle">
<i class="fa-solid fa-check"></i>
</button>
<?php else: ?>
<div class="rounded-circle bg-secondary d-flex align-items-center justify-content-center shadow" style="width: 150px; height: 150px;">
<i class="fa-solid fa-user-slash fa-4x text-white-50"></i>
</div>
<button type="button" onClick="ebene_init_photo_face();" class="btn btn-sm btn-primary position-absolute bottom-0 end-0 rounded-circle">
<i class="fa-solid fa-camera"></i>
</button>
<?php endif; ?>
</div>
<h5 class="mb-1 fw-bold"><?= $beneficiaire['numeroAdherent'] ?></h5>
<p class="text-muted small"><?= _("N° Famille") ?></p>
<div class="d-grid gap-2 mt-3">
<?php if($codeTypeContrat=="F"): ?>
<button type="button" class="btn btn-outline-info btn-sm" onClick="agent_commercial(<?= $idApporteur ?>);">
<i class="fa-solid fa-user-tie me-1"></i> <?= $libelleApporteur ?>
</button>
<?php endif; ?>
</div>
</div>
</div>
<?php if ($estsorti): ?>
<div class="alert alert-warning border-0 shadow-sm d-flex align-items-center">
<i class="fa-solid fa-door-open fa-2x me-3"></i>
<div>
<div class="fw-bold"><?= _("Sortie le") ?> : <?= dateLang($dateSortieBeneficiaire, $_SESSION['lang']) ?></div>
<small><?= $motifsortie ?></small>
</div>
</div>
<?php endif; ?>
</div>
</div>
<div class="row mt-4 g-3">
<?php if($controlerPlafondAdherent): ?>
<div class="col-md-6">
<div class="card border-0 shadow-sm">
<div class="card-header bg-primary text-white py-2 fw-bold small text-uppercase"><?= _("Plafond Famille") ?></div>
<div class="card-body p-0">
<div class="d-flex text-center border-bottom">
<div class="flex-fill p-2 border-end">
<small class="text-muted d-block"><?= _("Limite") ?></small>
<span class="fw-bold text-primary"><?= format_N($limite_adherent['plafondAdherent']) ?></span>
</div>
<div class="flex-fill p-2 border-end">
<small class="text-muted d-block"><?= _("Conso.") ?></small>
<span class="fw-bold text-danger"><?= format_N($limite_adherent['consommationAdherent']) ?></span>
</div>
<div class="flex-fill p-2 bg-light">
<small class="text-muted d-block"><?= _("Solde") ?></small>
<span class="fw-bold text-success"><?= format_N($limite_adherent['soldeAdherent']) ?></span>
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if($controlerPlafondBeneficiaire): ?>
<div class="col-md-6">
<div class="card border-0 shadow-sm">
<div class="card-header bg-dark text-white py-2 fw-bold small text-uppercase"><?= _("Plafond Individuel") ?></div>
<div class="card-body p-0">
<div class="d-flex text-center border-bottom">
<div class="flex-fill p-2 border-end">
<small class="text-muted d-block"><?= _("Limite") ?></small>
<span class="fw-bold text-primary"><?= format_N($limite_beneficiaire['plafondBeneficiaire']) ?></span>
</div>
<div class="flex-fill p-2 border-end">
<small class="text-muted d-block"><?= _("Conso.") ?></small>
<span class="fw-bold text-danger"><?= format_N($limite_beneficiaire['consommationBeneficiaire']) ?></span>
</div>
<div class="flex-fill p-2 bg-light">
<small class="text-muted d-block"><?= _("Solde") ?></small>
<span class="fw-bold text-success"><?= format_N($limite_beneficiaire['soldeBeneficiaire']) ?></span>
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<div class="card mt-1 shadow-sm">
<div class="card-header fw-bold d-flex justify-content-between">
<span><i class="fa-solid fa-shield-halved me-2"></i><?= _("Détail des Garanties") ?></span>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0" style="font-size: 0.9rem;">
<thead class="table-light">
<tr>
<th class="text-center"><?= _("Exercice") ?></th>
<th><?= _("Garantie") ?></th>
<th class="text-end"><?= _("Limite Contrat") ?></th>
<th class="text-center">%</th>
<th class="text-end"><?= _("Limite Vigueur") ?></th>
<th class="text-end"><?= _("Conso.") ?></th>
<th class="text-end fw-bold"><?= _("Solde") ?></th>
<th class="text-center"><?= _("Par tête") ?></th>
<th><?= _("Parent") ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($garantieadherents as $garantieadherent): ?>
<tr>
<td class="text-center"><?= $this->nettoyer($garantieadherent['exercieReference'])?></td>
<td class="fw-bold"><?= $this->nettoyer($garantieadherent['garantie'])?></td>
<td class="text-end"><?= format_N($this->nettoyer($garantieadherent['plafondAnnuel'])) ?></td>
<td class="text-center text-muted"><?= $this->nettoyer($garantieadherent['tauxAvenant']) ?>%</td>
<td class="text-end"><?= format_N($this->nettoyer($garantieadherent['plafond'])) ?></td>
<td class="text-end text-danger"><?= format_N($this->nettoyer($garantieadherent['consommation'])) ?></td>
<td class="text-end fw-bold text-success"><?= format_N($this->nettoyer($garantieadherent['solde'])) ?></td>
<td class="text-center">
<input type="checkbox" class="form-check-input" <?= ($this->nettoyer($garantieadherent['champApplication'])=='1') ? 'checked' : '' ?> disabled>
</td>
<td class="small text-muted"><?= $this->nettoyer($garantieadherent['garantieparentaffichage'])?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</form>
<div class="container-fluid mt-1">
<div class="card border-0 shadow-sm">
<div class="card-body">
<form enctype="multipart/form-data" action="Fichebeneficiaire/<?= $_SESSION['idBeneficiaire_C'] ?>/" method="post" class="row align-items-center g-3">
<div class="col-md-5">
<label class="form-label fw-bold small text-uppercase">
<?= ($_SESSION['lienPhoto_C'] > " ") ? _("Remplacer la photo") : _("Nouvelle photo") ?>
</label>
<input type="hidden" name="MAX_FILE_SIZE" value="500000" /> <input class="form-control form-control-sm" name="fichier_image_a_uploader" type="file" id="fichier_image_a_uploader" />
</div>
<div class="col-md-3">
<button type="submit" name="submit" class="btn btn-primary btn-sm mt-4 w-100">
<i class="fa-solid fa-cloud-arrow-up me-1"></i> <?= _("Mettre à jour") ?>
</button>
</div>
<div class="col-md-4">
<?php if ($message > " "): ?>
<div class="alert <?= ($message == 'Chargement réussi !') ? 'alert-success' : 'alert-danger' ?> m-0 py-2 small">
<?= $message ?>
</div>
<?php else: ?>
<div class="text-muted small italic">
<i class="fa-solid fa-file-image me-1"></i>
<?= _("Fichier actuel") ?> : <?= $beneficiaire['lienPhoto'] ?>
</div>
<?php endif; ?>
</div>
</form>
</div>
</div>
</div>
<!-- Responsive Area Chart -->
<div class="row mt-4">
<div class="col-12 mb-4">
<div class="card shadow h-100">
<div class="card-header py-3 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 type="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>
</div>
<!-- Bar Chart Section -->
<div class="row mt-4">
<div class="col-12 mb-4">
<div class="card shadow h-100">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary"><?= _("Dépenses par garantie") ?></h6>
<button type="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>
<?php include 'faceebene/ebenetraitementimage.php'; ?>
<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 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
}
}
}
}
});
// Boutons d'export PDF
document.getElementById('exportTrendBtn').addEventListener('click', () => {
exportChartToPDF('expenseTrendChart', 'evolution_depenses_mensuelles');
});
document.getElementById('exportBarBtn').addEventListener('click', () => {
exportChartToPDF('depensesChart', 'depenses_par_garantie');
});
})();
</script>