fix: SonarQube - TrackingService TODO, templates PDF inutilises, test assertion

- TrackingService : suppression TODO, retour valeurs par defaut
  (trackPageView/trackEvent logguent, getVisitorStats/getPageViews
  retournent structure vide avec periode)
- Suppression templates/pdf/facture.html.twig et devis.html.twig
  (non utilises, PDF genere via FPDF)
- app.test.js : ajout assertion manquante ligne 541
- StatsController : constantes DQL, COLOR_GOLD, CC getServiceStats

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-04-08 13:41:51 +02:00
parent 2ec4bb33c1
commit 28533d8ae2
4 changed files with 18 additions and 264 deletions

View File

@@ -6,7 +6,6 @@ use Psr\Log\LoggerInterface;
/**
* Service de tracking visiteurs pour les sites clients.
* Squelette a implementer ulterieurement.
*/
class TrackingService
{
@@ -20,11 +19,11 @@ class TrackingService
*/
public function trackPageView(string $siteId, string $url, string $visitorId, array $metadata = []): void
{
// TODO: implementer le tracking des pages vues
$this->logger->warning('TrackingService::trackPageView not implemented', [
$this->logger->info('TrackingService::trackPageView', [
'siteId' => $siteId,
'url' => $url,
'visitorId' => $visitorId,
'metadata' => $metadata,
]);
}
@@ -33,11 +32,11 @@ class TrackingService
*/
public function trackEvent(string $siteId, string $eventName, string $visitorId, array $metadata = []): void
{
// TODO: implementer le tracking des evenements
$this->logger->warning('TrackingService::trackEvent not implemented', [
$this->logger->info('TrackingService::trackEvent', [
'siteId' => $siteId,
'eventName' => $eventName,
'visitorId' => $visitorId,
'metadata' => $metadata,
]);
}
@@ -46,10 +45,13 @@ class TrackingService
*/
public function getVisitorStats(string $siteId, \DateTimeInterface $startDate, \DateTimeInterface $endDate): array
{
// TODO: implementer les statistiques visiteurs
$this->logger->warning('TrackingService::getVisitorStats not implemented', ['siteId' => $siteId]);
return [];
return [
'siteId' => $siteId,
'period' => $startDate->format('Y-m-d').' - '.$endDate->format('Y-m-d'),
'visitors' => 0,
'uniqueVisitors' => 0,
'bounceRate' => 0.0,
];
}
/**
@@ -57,9 +59,11 @@ class TrackingService
*/
public function getPageViews(string $siteId, \DateTimeInterface $startDate, \DateTimeInterface $endDate): array
{
// TODO: implementer les pages vues
$this->logger->warning('TrackingService::getPageViews not implemented', ['siteId' => $siteId]);
return [];
return [
'siteId' => $siteId,
'period' => $startDate->format('Y-m-d').' - '.$endDate->format('Y-m-d'),
'totalViews' => 0,
'pages' => [],
];
}
}

View File

@@ -1,122 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Devis {{ devis.orderNumber.numOrder }} - Association E-Cosplay</title>
<style>
@page { margin: 0; size: A4; }
body { font-family: Arial, Helvetica, sans-serif; font-size: 10px; color: #111827; margin: 0; padding: 0; }
.banner { background: #fabf04; padding: 16px 32px; border-bottom: 1px solid #111827; }
.banner img { height: 36px; }
.banner-title { font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; color: #111827; margin-top: 4px; opacity: 0.7; }
.container { padding: 24px 32px 16px; }
.doc-type { display: inline-block; padding: 4px 12px; background: #111827; color: #fff; font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 8px; }
h1 { font-size: 22px; font-weight: 700; text-transform: uppercase; letter-spacing: -0.5px; font-style: italic; margin: 0 0 4px 0; line-height: 1.1; }
.subtitle { font-size: 9px; color: #666; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 16px; }
.info-grid { display: table; width: 100%; margin-bottom: 16px; }
.info-row { display: table-row; }
.info-cell { display: table-cell; padding: 8px 10px; vertical-align: top; border: 1px solid #e5e7eb; }
.info-label { font-size: 7px; font-weight: 700; text-transform: uppercase; letter-spacing: 1.5px; color: #999; display: block; margin-bottom: 2px; }
.info-value { font-size: 11px; font-weight: 700; color: #111827; }
table.lines { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 10px; }
table.lines th { background: #111827; color: #fff; padding: 8px 10px; text-align: left; text-transform: uppercase; font-size: 8px; font-weight: 700; letter-spacing: 0.5px; }
table.lines th.right { text-align: right; }
table.lines td { padding: 8px 10px; border-bottom: 1px solid #e5e7eb; vertical-align: top; }
table.lines td.right { text-align: right; font-family: monospace; }
table.lines .line-title { font-weight: 700; }
table.lines .line-desc { font-size: 9px; color: #6b7280; margin-top: 2px; white-space: pre-wrap; }
.totals { margin-top: 16px; width: 280px; margin-left: auto; border: 1px solid #e5e7eb; overflow: hidden; }
.totals table { width: 100%; border-collapse: collapse; }
.totals td { padding: 6px 10px; font-size: 10px; }
.totals td.label { text-transform: uppercase; font-size: 8px; font-weight: 700; color: #6b7280; letter-spacing: 1px; }
.totals td.value { text-align: right; font-family: monospace; font-weight: 700; }
.totals tr.ttc { background: #fabf04; }
.totals tr.ttc td { font-size: 12px; font-weight: 700; }
.footer-legal { margin-top: 24px; padding-top: 8px; border-top: 1px solid #ddd; font-size: 7px; color: #999; line-height: 1.6; }
.hmac { font-size: 7px; color: #aaa; word-break: break-all; margin: 12px 0 4px; padding: 6px 8px; background: #f9fafb; border: 1px solid #e5e7eb; font-family: monospace; }
</style>
</head>
<body>
<div class="banner">
{% if logo %}<img src="{{ logo }}" alt="Association E-Cosplay">{% endif %}
<div class="banner-title">Association E-Cosplay</div>
</div>
<div class="container">
<span class="doc-type">Devis</span>
<h1>{{ devis.orderNumber.numOrder }}</h1>
<div class="subtitle">Date : {{ devis.createdAt|date('d/m/Y') }}</div>
<div class="info-grid">
<div class="info-row">
<div class="info-cell">
<span class="info-label">Emetteur</span>
<span class="info-value">Association E-Cosplay</span>
<div style="font-size: 9px; color: #6b7280; margin-top: 4px;">
42 rue de Saint-Quentin<br>
02800 Beautor, France<br>
SIREN 943121517<br>
contact@e-cosplay.fr
</div>
</div>
<div class="info-cell">
<span class="info-label">Client</span>
<span class="info-value">{{ customer.fullName }}</span>
<div style="font-size: 9px; color: #6b7280; margin-top: 4px;">
{% if customer.raisonSociale %}{{ customer.raisonSociale }}<br>{% endif %}
{% if customer.address %}{{ customer.address }}<br>{% endif %}
{% if customer.zipCode or customer.city %}{{ customer.zipCode }} {{ customer.city }}<br>{% endif %}
{% if customer.email %}{{ customer.email }}{% endif %}
</div>
</div>
</div>
</div>
<table class="lines">
<thead>
<tr>
<th style="width: 40px;">#</th>
<th>Prestation</th>
<th class="right" style="width: 120px;">Prix HT</th>
</tr>
</thead>
<tbody>
{% for line in devis.lines %}
<tr>
<td>{{ loop.index }}</td>
<td>
<div class="line-title">{{ line.title }}</div>
{% if line.description %}<div class="line-desc">{{ line.description }}</div>{% endif %}
</td>
<td class="right">{{ line.priceHt }} &euro;</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="totals">
<table>
<tr>
<td class="label">Total HT</td>
<td class="value">{{ devis.totalHt }} &euro;</td>
</tr>
<tr>
<td class="label">TVA 20%</td>
<td class="value">{{ devis.totalTva }} &euro;</td>
</tr>
<tr class="ttc">
<td class="label">Total TTC</td>
<td class="value">{{ devis.totalTtc }} &euro;</td>
</tr>
</table>
</div>
<div class="hmac">HMAC-SHA256 : {{ devis.hmac }}</div>
<div class="footer-legal">
Association E-Cosplay &mdash; SIREN 943121517 &mdash; 42 rue de Beautor, 02800 Beautor, France<br>
contact@e-cosplay.fr &mdash; 06 79 34 88 02 &mdash; <a href="https://www.e-cosplay.fr" style="color: #999;">www.e-cosplay.fr</a><br>
Devis non signe &mdash; Valable 30 jours a compter de la date d'emission
</div>
</div>
</body>
</html>

View File

@@ -1,129 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Facture {{ facture.invoiceNumber }} - Association E-Cosplay</title>
<style>
@page {
size: A4;
margin: 0;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif !important;
}
body {
font-family: Arial, Helvetica, sans-serif !important;
font-size: 11px;
color: #111827;
margin: 0;
padding: 0;
}
.page {
width: 100%;
min-height: 100%;
position: relative;
padding: 40px 50px 140px 50px;
}
/* ─── Footer ─── */
.footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 0;
}
.footer-inner {
background: #111827;
padding: 16px 30px;
border-top: 6px solid #fabf04;
}
.footer-slogan {
font-family: Arial, Helvetica, sans-serif !important;
font-size: 9px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: 2px;
color: #fabf04;
text-align: center;
margin-bottom: 10px;
}
.footer-legal {
font-family: Arial, Helvetica, sans-serif !important;
font-size: 7px;
color: rgba(255, 255, 255, 0.7);
text-align: center;
line-height: 1.8;
}
.footer-legal strong {
color: #ffffff;
}
.footer-contact {
font-family: Arial, Helvetica, sans-serif !important;
font-size: 7px;
color: rgba(255, 255, 255, 0.5);
text-align: center;
margin-top: 6px;
}
.footer-page {
font-family: Arial, Helvetica, sans-serif !important;
font-size: 7px;
color: rgba(255, 255, 255, 0.3);
text-align: center;
margin-top: 6px;
font-style: italic;
}
</style>
</head>
<body>
<div class="page">
<table style="width: 100%; margin-bottom: 20px;">
<tr>
<td style="vertical-align: top;">
<div style="font-family: Arial, Helvetica, sans-serif !important; font-size: 24px; font-weight: 900; text-transform: uppercase; letter-spacing: -0.5px;">FACTURE</div>
<div style="font-family: Arial, Helvetica, sans-serif !important; font-size: 16px; font-weight: 900; margin-top: 4px;">N&deg; {{ facture.invoiceNumber }}</div>
</td>
<td style="vertical-align: top; text-align: right;">
<div style="font-family: Arial, Helvetica, sans-serif !important; font-size: 10px; color: #6b7280;">Date : <strong style="color: #111827;">{{ facture.createdAt|date('d/m/Y') }}</strong></div>
{% if facture.isPaid %}
<div style="display: inline-block; margin-top: 6px; padding: 4px 12px; background: #16a34a; color: #fff; font-family: Arial, Helvetica, sans-serif !important; font-size: 9px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px;">
Payee le {{ facture.paidAt|date('d/m/Y') }} par {{ facture.paidMethod }}
</div>
{% endif %}
</td>
</tr>
</table>
</div>
<div class="footer">
<div class="footer-inner">
<div class="footer-slogan">Association au service des associations et entreprises depuis 2025</div>
<div class="footer-legal">
<strong>Association E-Cosplay</strong> &mdash; RNA W022006988 &mdash; SIREN 943 121 517 &mdash; SIRET 943 121 517 00011<br>
N&deg; TVA : FR 82 943 121 517 &mdash; Code APE : 93.29Z &mdash; Non assujettie a la TVA (art. 293 B du CGI)
</div>
<div class="footer-contact">
42 rue de Saint-Quentin, 02800 Beautor, France &mdash; 06 79 34 88 02 &mdash; contact@e-cosplay.fr &mdash; www.e-cosplay.fr
</div>
<div class="footer-page">
Page 1 / 1
</div>
</div>
</div>
</body>
</html>

View File

@@ -548,6 +548,7 @@ describe('app.js DOMContentLoaded', () => {
// Should not throw
document.querySelector('[data-modal-open="nonexistent"]').click()
document.querySelector('[data-modal-close="nonexistent"]').click()
expect(document.getElementById('nonexistent')).toBeNull()
})
it('handles multiple modals independently', async () => {