Files
crm_ecosplay/templates/dns_report/index.html.twig
Serreau Jovann 8b35e2b6d2 feat: comptabilite + prestataires + rapport financier + stats dynamiques
Comptabilite (Super Admin) :
- ComptabiliteController avec 7 exports CSV/JSON compatibles SAGE
  (journal ventes, grand livre, FEC, balance agee, reglements,
  commissions Stripe 1.5%+0.25E, couts services)
- Export PDF via ComptaPdf (FPDF) avec bloc legal pre-rempli,
  tableau pagine, champ signature DocuSeal
- Signature electronique DocuSeal + callback + envoi email signe
  avec template dedie (compta_export_signed.html.twig)
- Rapport financier public (RapportFinancierPdf) : recettes par
  service, depenses (Stripe, infra, prestataires), bilan excedent/deficit
- Codes comptables clients EC-XXXX (plus de 411xxx)

Prestataires (Super Admin) :
- Entite Prestataire (raisonSociale, siret, email, phone, adresse)
- Entite FacturePrestataire (numFacture, montantHt, montantTtc,
  year, month, isPaid, PDF via Vich)
- CRUD complet avec recherche SIRET via proxy API data.gouv.fr
- Commande cron app:reminder:factures-prestataire (5 du mois)
- Factures prestataires integrees dans export couts services
- Sidebar Super Admin : entree Prestataires + Comptabilite

Stats (/admin/stats) :
- Cout prestataire dynamique depuis FacturePrestataire
- Fusion Infra + Prestataire en "Cout de fonctionnement"
- Commission Stripe corrigee (1.5% + 0.25E par transaction)

Divers :
- DocuSealService::sendComptaForSignature() + getApi()
- Customer::generateCodeComptable() format EC-XXXX-XXXXX
- Protection double prefixe EC- a la creation client
- Bouton regenerer PDF cache quand advert state=accepted
- Modals sans script inline (data-modal-open/close dans app.js)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:39:31 +02:00

130 lines
7.1 KiB
Twig

{% extends 'base.html.twig' %}
{% block title %}Rapport DNS - Association E-Cosplay{% endblock %}
{% block header %}
<header class="sticky top-0 z-50 glass-heavy" >
<div class="flex justify-center items-center h-16">
<a href="{{ path('app_home') }}" aria-label="CRM E-Cosplay - Accueil">
<img class="h-10 md:h-12 w-auto" src="{{ 'logo.jpg' | imagine_filter('logo') }}" alt="CRM E-Cosplay" loading="eager">
</a>
</div>
</header>
{% endblock %}
{% block body %}
<div class="page-container">
<h1 class="text-2xl font-bold heading-page mb-4">Rapport de configuration DNS</h1>
<p class="text-sm text-gray-500 mb-8">Genere le {{ date|date('d/m/Y H:i:s') }} par <strong>E-Infra</strong></p>
{# ─── Resume ─── #}
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
<div class="glass p-4" style="border-left: 3px solid #16a34a;">
<p class="text-2xl font-bold text-green-600">{{ successes|length }}</p>
<p class="text-xs font-bold uppercase tracking-wider text-gray-500">Verifications OK</p>
</div>
{% if errors|length > 0 %}
<div class="glass p-4" style="border-left: 3px solid #dc2626;">
<p class="text-2xl font-bold text-red-600">{{ errors|length }}</p>
<p class="text-xs font-bold uppercase tracking-wider text-gray-500">Erreurs</p>
</div>
{% endif %}
{% if warnings|length > 0 %}
<div class="glass p-4" style="border-left: 3px solid #f59e0b;">
<p class="text-2xl font-bold text-amber-600">{{ warnings|length }}</p>
<p class="text-xs font-bold uppercase tracking-wider text-gray-500">Avertissements</p>
</div>
{% endif %}
</div>
{# ─── Detail par domaine ─── #}
{% for domainData in domainResults %}
<div class="mb-8">
<h2 class="text-xl font-bold mb-4" style="border-bottom: 2px solid #fabf04; padding-bottom: 4px; display: inline-block;">{{ domainData.domain }}</h2>
<div class="glass overflow-hidden">
<table class="w-full text-xs">
<thead>
<tr class="glass-dark" >
<th class="px-3 py-2 text-left font-bold uppercase tracking-wider text-white/80" style="width: 90px;">Source</th>
<th class="px-3 py-2 text-left font-bold uppercase tracking-wider text-white/80">Verification</th>
<th class="px-3 py-2 text-left font-bold uppercase tracking-wider text-white/80">Attendu</th>
<th class="px-3 py-2 text-left font-bold uppercase tracking-wider text-white/80">Dig (actuel)</th>
<th class="px-3 py-2 text-left font-bold uppercase tracking-wider text-white/80">Cloudflare</th>
<th class="px-3 py-2 text-center font-bold uppercase tracking-wider text-white/80" style="width: 50px;">Statut</th>
</tr>
</thead>
<tbody>
{% for check in domainData.checks %}
<tr class="border-b border-white/10 hover:bg-white/30 transition-colors">
<td class="px-3 py-2 font-bold text-gray-500 align-top">
<span class="inline-block px-1.5 py-0.5text-[9px] font-bold
{% if 'AWS' in check.type %}bg-orange-500/20 text-orange-700
{% elseif 'Mailcow' in check.type %}bg-purple-500/20 text-purple-700
{% elseif 'Cloudflare' in check.type %}bg-blue-500/20 text-blue-700
{% else %}bg-gray-500/20 text-gray-600{% endif %}">
{{ check.type }}
</span>
</td>
<td class="px-3 py-2 font-bold align-top">{{ check.label }}</td>
<td class="px-3 py-2 text-gray-500 align-top break-all">{{ check.expected|default('—') }}</td>
<td class="px-3 py-2 align-top break-all
{% if check.status == 'ok' %}text-green-600
{% elseif check.status == 'error' %}text-red-600
{% else %}text-amber-600{% endif %}">
{{ check.dig|default('—') }}
</td>
<td class="px-3 py-2 align-top break-all
{% if check.cf_status|default('') == 'ok' %}text-green-600
{% elseif check.cf_status|default('') == 'error' %}text-red-600
{% else %}text-gray-400{% endif %}">
{{ check.cloudflare|default('—') }}
</td>
<td class="px-3 py-2 text-center align-top">
{% if check.status == 'ok' %}
<span class="inline-block w-5 h-5 bg-green-500/20 text-green-600 font-bold leading-5">&#10003;</span>
{% elseif check.status == 'error' %}
<span class="inline-block w-5 h-5 bg-red-500/20 text-red-600 font-bold leading-5">&#10007;</span>
{% else %}
<span class="inline-block w-5 h-5 bg-amber-500/20 text-amber-600 font-bold leading-5">&#9888;</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endfor %}
{# ─── Erreurs detaillees ─── #}
{% if errors|length > 0 %}
<div class="mb-6">
<h2 class="text-lg font-bold text-red-600 mb-3">Erreurs a corriger</h2>
<div class="glass p-4" style="border-left: 3px solid #dc2626;">
<ul class="text-sm space-y-1">
{% for error in errors %}
<li class="text-red-700">&#10007; {{ error }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% if warnings|length > 0 %}
<div class="mb-6">
<h2 class="text-lg font-bold text-amber-600 mb-3">Avertissements</h2>
<div class="glass p-4" style="border-left: 3px solid #f59e0b;">
<ul class="text-sm space-y-1">
{% for warning in warnings %}
<li class="text-amber-700">&#9888; {{ warning }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
<p class="text-xs text-gray-400 mt-8">Rapport par <strong>E-Infra</strong> - Service de monitoring d'infra</p>
</div>
{% endblock %}